Tastypie with app / x-www-form-urlencoded

It’s hard for me to understand what my next steps should be. I use tastypie to create an API for my web application.

From another application, in particular ifbyphone.com, I get POST without headers that look 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 applies to my server. But tastypie complains about the POST format.

{"error_message": "The specified format" application / x-www-form-urlencoded "did not have a deserialization method. Check the formats and content_types on your Serializer.", "Traceback": "Traceback (last last call): \ n \ n File \ "/ usr / local / lib / python 2.7 / dist-packages / tastypie / resources.py \"

I also get the same message when I try to execute POST data using curl, which I consider "the same basic process used by the ifbyphone POST method:

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

So, if my problem is actually what is indicated in the error message and there is no deserialization method, how would I start writing?

#### Update ######

With some help from this commit ( https://github.com/toastdriven/django-tastypie/commit/7c5ea699ff6a5e8ba0788f23446fa3ac31f1b8bf ) I played with writing my own serializer by copying the basic structure from the documentation ( https://django-tastyp.s. 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 
+6
source share
2 answers

This worked as expected when I edited my resource model to actually use the serializer class that I created. This was unclear 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 
+14
source

I would add a modification from_urlencode mentioned in the Brandon Bertelsen post to work better with international characters:

 def from_urlencode(self, data, options=None): """ handles basic formencoded url posts """ qs = {} for k, v in urlparse.parse_qs(data).iteritems(): value = v if len(v)>1 else v[0] value = value.encode("latin-1").decode('utf-8') qs[k] = value return qs 

I’m not sure if this is due to environmental considerations on my side, but I found that when using the next line “ÁáÄÅåééíííññññóóÖöÚúÜü” and the original function, I ran into some problems.

When this string receives the URL, it turns into: "% C3% 81% C3% A1% C3% 84% C3% A4% C3% 85% C3% A5% C3% 89% C3% A9% C3% 8D% C3% AD% C3% 91% C3% B1% C3% 93% C3% B3% C3% 96% C3% B6% C3% 9A% C3% BA% C3% 9C% C3% BC "

When it receives the URL decoding, we have: u '\ xc3 \ x81 \ xc3 \ xa1 \ xc3 \ x84 \ xc3 \ xa4 \ xc3 \ x85 \ xc3 \ xa5 \ xc3 \ x89 \ xc3 \ xa9 \ xc3 \ x8d \ xc3 \ XAD \ xc3 \ x91 \ xc3 \ XB1 \ xc3 \ x93 \ xc3 \ xb3 \ xc3 \ x96 \ xc3 \ XB6 \ xc3 \ X9a \ xc3 \ Xba \ xc3 \ x9c \ xc3 \ XBC '

The problem is that this line looks like unicode, but actually it isn’t, so the line above is converted to: "

I found that if I interpreted the value of the decoded URL as latin-1 and then decoded it for UTF-8, I got the correct source string.

0
source

All Articles