Tastypie与application / x-www-form-urlencoded

时间:2012-12-28 18:38:50

标签: python django tastypie

我在确定下一步应该是什么时遇到一些困难。我正在使用tastypie为我的Web应用程序创建API。

从另一个应用程序,特别是ifbyphone.com,我收到一个没有标题的POST,看起来像这样:

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

现在,我在服务器日志中看到这是在点击我的服务器。但是tastypie正在抱怨POST的格式。

  

{“error_message”:“指示的格式   'application / x-www-form-urlencoded'没有可用的反序列化   方法。请检查您的formatscontent_types   Serializer。“,”traceback“:”Traceback(最近一次调用最后一次):\ n \ n   文件\“/ usr / local / lib / python2.7 / dist-packages / tastypie / resources.py \”

当我尝试使用curl发布原始数据时,我也收到相同的消息,我“相信”与ifbyphone的POST方法使用的基本过程相同:

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

因此,假设我的问题实际上是错误消息中指定的内容,并且没有反序列化方法,我将如何编写一个?

####更新######

在这个提交的帮助下(https://github.com/toastdriven/django-tastypie/commit/7c5ea699ff6a5e8ba0788f23446fa3ac31f1b8bf),我一直在编写自己的序列化程序,从文档中复制基本框架(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

2 个答案:

答案 0 :(得分:14)

当我编辑我的资源模型以实际使用我创建的序列化程序类时,这可以正常工作。这在文档中并不清楚。

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

答案 1 :(得分:0)

我会在Brandon Bertelsen的帖子中添加对from_urlencode的修改,以便更好地与国际角色合作:

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

我不确定这是否是因为我身边的环境原因,但我发现当使用以下字符串“ÁáÄäÅåÉéÍíÑñÓóÖöÚúÜü”和原始功能时,我遇到了一些问题。

当此字符串获得URL编码时,它将变为: “%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“

当这个URL被解码时,我们有: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'

这里的问题是这个字符串似乎是unicode,但它实际上不是,所以上面的字符串被转换为:“ÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÔ

我发现如果我将URL解码后的值解释为latin-1,然后将其解码为UTF-8,我就会得到正确的原始字符串。