Django CBV request.POST 不可变

我们知道 Django 框架支持 CBV 的方式来编写视图函数,从而支持 http 请求的各种方法(GET, POST 等)。下图是一个典型的实现。

class HelloClassView(View):
    def get(self,request):
        print 'This is the get method of HelloClassView'
        return render(request, 'helloclassview.html')

    def post(self,request):
        print 'This is the post method of HelloClassView'
        print 'request.POST = {0}, type(request.POST) = {1}'.format(request.POST, type(request.POST))
        print 'request.body = {0}'.format(request.body)
        # 这是本文要讨论的重点代码:
        # tmp =request.POST
        # print tmp.get('username')
        # print tmp.pop('username')
        return HttpResponse('POST OK')

我们的客户端可以用 request 包来模拟

import requests
input_dict = {'username':'admin', 'password':'start01all'}

url = 'http://192.168.56.101:8082/HelloClassView/'
res = requests.post(url, data=input_dict)
print 'type(res.headers) = {0}, res.headers = {1}'.format(type(res.headers), res.headers)
print 'type(res.text) = {0}, res.text = {1}'.format(type(res.text), res.text)
print 'res.status_code = {0}'.format(res.status_code)

视图类的 post 函数收到客户端的 POST 请求后,其的输出是:

This is the post method of HelloClassView
request.POST = <QueryDict: {u'username': [u'admin'], u'password': [u'start01all']}>, type(request.POST) = <class 'django.http.request.QueryDict'>
request.body = username=admin&password=start01all

可以看到 resquest.POST 的类型是 django.http.request.QueryDict,根据该类的文档可知
By default QueryDicts are immutable, though the copy() method will always return a mutable copy.
所以当我们在视图函数中 企图去修改 request.POST 的值时,就会遇到如下异常:
This QueryDict instance is immutable
需要注意的是,上面说的是你的后端代码使用的是 Django 框架原生的 CBV 即你继承的 View类。但是如果你的后端使用了 DjangoRestFramework 框架继承的是 ModelViewSet 的话,获取前端 POST 数据的方法是 tmp = request.data。 而这个tmp 是可变的就是普通的 dict,所以可以像平时操作 dict 来操作它!

所以如果我们需要修改 request.POST, 有如下两种方式:这里推荐第一种方式
方法1:

data=request.POST.copy()

方法2:

data=request.POST
# 记住旧的方式
_mutable = data._mutable

# 设置_mutable为True
data._mutable = True

# 改变你想改变的数据
do something;做我们想要做的事
data['name']='chenxinming'
# 恢复_mutable原来的属性
data._mutable = _mutable
发布了44 篇原创文章 · 获赞 0 · 访问量 3955

猜你喜欢

转载自blog.csdn.net/cpxsxn/article/details/100127392