Tastypie with application/x-www-form-urlencoded

匿名 (未验证) 提交于 2019-12-03 08:46:08

问题:

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 

回答1:

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 


回答2:

I would add a modification to the from_urlencode mentioned in Brandon Bertelsen's 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 

When this string gets URL encoded, 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 this gets URL decoded, 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'

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



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!