6

我有点难以弄清楚我的下一步应该是什么。我正在使用tastepie 为我的Web 应用程序创建一个API。

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

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

现在,我在我的服务器日志中看到这正在击中我的服务器。但美味派抱怨 POST 的格式。

{“error_message”:“指示的格式 'application/x-www-form-urlencoded' 没有可用的反序列化方法。请检查您的formatscontent_types在您的序列化器上。”,“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
4

2 回答 2

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
于 2012-12-28T20:34:20.050 回答
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,我得到了正确的原始字符串。

于 2016-09-28T00:21:44.717 回答