Search code examples
pythondjangotastypie

Tastypie with application/x-www-form-urlencoded


I'm having a bit of difficulty figuring out what my next steps should be. I am using tastypie to create an API for my web application.

From another application, specifically ifbyphone.com, I am receiving a POST with no headers that looks something like this:

post data:http://myapp.com/api/
callerid=1&someid=2&number=3&result=Answered&phoneid=4

Now, I see in my server logs that this is hitting my server.But tastypie is complaining about the format of the POST.

{"error_message": "The format indicated 'application/x-www-form-urlencoded' had no available deserialization method. Please check your formats and content_types on your Serializer.", "traceback": "Traceback (most recent call last):\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\"

I also receive the same message when I try to POST raw data using curl, which I "believe" is the same basic process being used by ifbyphone's POST method:

curl -X POST --data 'callerid=1&someid=2&number=3&duration=4&phoneid=5' http://myapp.com/api/

So, assuming my problem is actually what is specified in the error message, and there is no deserialization method, how would I go about writing one?

#### Update ######

With some help from this commit ( https://github.com/toastdriven/django-tastypie/commit/7c5ea699ff6a5e8ba0788f23446fa3ac31f1b8bf ) I've been playing around with writing my own serializer, copying the basic framework from the documentation ( https://django-tastypie.readthedocs.org/en/latest/serialization.html#implementing-your-own-serializer )

import urlparse
from tastypie.serializers import Serializer

class urlencodeSerializer(Serializer):
    formats = ['json', 'jsonp', 'xml', 'yaml', 'html', 'plist', 'urlencode']
    content_types = {
        'json': 'application/json',
        'jsonp': 'text/javascript',
        'xml': 'application/xml',
        'yaml': 'text/yaml',
        'html': 'text/html',
        'plist': 'application/x-plist',
        'urlencode': 'application/x-www-form-urlencoded',
        }
    def from_urlencode(self, data,options=None):
        """ handles basic formencoded url posts """
        qs = dict((k, v if len(v)>1 else v[0] )
            for k, v in urlparse.parse_qs(data).iteritems())
        return qs

    def to_urlencode(self,content): 
        pass

Solution

  • This worked as expected when I edited my resource model to actually use the serializer class I created. This was not clear in the documentation.

    class urlencodeSerializer(Serializer):
        formats = ['json', 'jsonp', 'xml', 'yaml', 'html', 'plist', 'urlencode']
        content_types = {
            'json': 'application/json',
            'jsonp': 'text/javascript',
            'xml': 'application/xml',
            'yaml': 'text/yaml',
            'html': 'text/html',
            'plist': 'application/x-plist',
            'urlencode': 'application/x-www-form-urlencoded',
            }
        def from_urlencode(self, data,options=None):
            """ handles basic formencoded url posts """
            qs = dict((k, v if len(v)>1 else v[0] )
                for k, v in urlparse.parse_qs(data).iteritems())
            return qs
    
        def to_urlencode(self,content): 
            pass
    
    MyModelResource(ModelResoucre):
        class Meta:
            ...
            serializer = urlencodeSerializer() # IMPORTANT