资讯专栏INFORMATION COLUMN

Django解析Angular的POST数据

Java_oldboy / 3442人阅读

摘要:在使用和的过程中,遇到过一个向数据的问题。以上将会打印出而我们期望是这样的结果出现这种问题是因为默认发送的数据格式是而不是,而的无法解析,所以才会出现上面的结果。和最大的区别是将每个存在列表当中,并且是不可修改类型。

在使用Django和Angular的过程中,遇到过一个Angular向Django POST数据的问题。

// Angular
$http({
    url: "myviews",
    method: "POST",
    data: {"text": "hello world", "date": "2017-01-04"}
})
# Django
def myviews(request):
    print request.POST
    print request.body

以上将会打印出


u"{"text": "hello world", "date": "2017-01-04"}"

而我们期望是这样的结果


u"{"text": "hello world", "date": "2017-01-04"}"

出现这种问题是因为Angular默认发送的数据格式是JSON而不是urlencode,而Django的request.POST无法解析JSON,所以才会出现上面的结果。

解决的办法有很多,最简单粗暴的办法就是在每个视图函数里面都将request.body进行解析

def myviews(request):
    data = urlencode(json.loads(request.body))
    q_data = QueryDict(data)

我们可以把这类操作提取出来,写成Middlerware,在request请求到达视图函数之前就给统一处理好

class JSONMiddleware(object):
    """
    Process application/json requests data from GET and POST requests.
    """
    def process_request(self, request):
        if "application/json" in request.META["CONTENT_TYPE"]:
            data = json.loads(request.body)
            q_data = QueryDict("", mutable=True)

            for key, value in data.iteritems():
                if isinstance(value, list):
                    for x in value:
                        q_data.update({key: x})
                else:
                    q_data.update({key: value})

            if request.method == "GET":
                request.GET = q_data

            if request.method == "POST":
                request.POST = q_data
        return None

因为有的request请求当中没有CONTENT-TYPE这个Header,所以我们需要判断一下,之所以不简单的转化成Dict而是QueryDict是因为遵循一致性的原则,我们想要将结果绑定在request.GET或者request.POST上面,而它们都是QueryDict类型。QueryDictDict最大的区别是QueryDict将每个value存在列表当中,并且QueryDict是不可修改类型。所以当value是列表时我们也必须做一下判断,否则整个列表将作为一个元素存入QueryDict的列表当中。

a = {"a": [123, 456, 444], "b": 456}
# 不做判断
data = QueryDict("", mutable=True)
for k, v in a.iteritems():
    data.update({k: v})
print data

# 做判断
data = QueryDict("" mutable=True)
for k, v in a.iteritems():
    if isinstance(v, list):
        for x in value:
            data.update({k: x})
    else:
        data.update({k: v})
print data

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/38308.html

相关文章

  • Django搭建个人博客:使用Form表单类发表新文章

    摘要:一些表单界面元素文本框或复选框非常简单并内置在中,而其他会复杂些像弹出日期选择等操作控件。和标签中的属性指定了当前文本框提交的数据的名称,它必须与表单类中的字段名称对应,否则服务器无法将字段和数据正确的对应起来。 前面我们已经学会如何用Markdown语法书写文章了。 但是还有问题呀。之前写文章都是在后台中进行的,万一有别的普通用户也要发表文章怎么办?万一我想拓展些后台中没有的提交验证...

    Java3y 评论0 收藏0
  • Django 博客开发教程 8 - 博客文章详情页

    摘要:对文章详情视图而言,每篇文章对应着不同的。在博客文章详情页追梦人物的博客的评论区留言。将问题的详细描述通过邮件发送到,一般会在小时内回复。更多教程,请访问追梦人物的博客。 首页展示的是所有文章的列表,当用户看到感兴趣的文章时,他点击文章的标题或者继续阅读的按钮,应该跳转到文章的详情页面来阅读文章的详细内容。现在让我们来开发博客的详情页面,有了前面的基础,开发流程都是一样的了:首先配置 ...

    pkwenda 评论0 收藏0
  • FCC 成都社区·技术周刊 第 13 期

    摘要:前端支持同域才能发送本月初,浏览器发布。所谓攻击,就是使用真实的进行恶意行为。链接发布此次发布亮点包括类型以及对和映射对象类型中的符号和数字文字的支持。但直到看到了,总算觉得社区又进了一步。微信已将对弈源码和训练好的模型开源。 【前端】 1、Firefox 60 支持同域才能发送 Cookie 本月初,Firefox 60 浏览器发布。它有一个很大的亮点,就是它解决了 CSRF 攻击。...

    Seay 评论0 收藏0
  • FCC 成都社区·技术周刊 第 13 期

    摘要:前端支持同域才能发送本月初,浏览器发布。所谓攻击,就是使用真实的进行恶意行为。链接发布此次发布亮点包括类型以及对和映射对象类型中的符号和数字文字的支持。但直到看到了,总算觉得社区又进了一步。微信已将对弈源码和训练好的模型开源。 【前端】 1、Firefox 60 支持同域才能发送 Cookie 本月初,Firefox 60 浏览器发布。它有一个很大的亮点,就是它解决了 CSRF 攻击。...

    chnmagnus 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<