Python django 修改请求对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18930234/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
django modifying the request object
提问by user2801567
I already have a django project and it logical like those:
我已经有一个 django 项目,它的逻辑如下:
url: URL?username=name&pwd=passwd
url: URL?username=name&pwd=passwd
view:
看法:
def func(request):
dic = request.GET
username = dic.get("username")
pwd = dic.get("pwd")
but now we need encrypt the data. Then, the request become this:
但现在我们需要加密数据。然后,请求变成这样:
url: URL?crypt=XXXXXXXXXX (XXXXXXXX is encrypted str for "username=name&pwd=passwd")
url: URL?crypt=XXXXXXXXXX(XXXXXXXX 是“username=name&pwd=passwd”的加密字符串)
so I need modify every view function. But now I want decrypt in django middleware to prevent from modifying every view function.
所以我需要修改每个视图函数。但是现在我想在 django 中间件中解密以防止修改每个视图函数。
but when I modify request.GET, I recive error msg "This QueryDict instance is immutable". How can I modify it?
但是当我修改 request.GET 时,我收到错误消息“此 QueryDict 实例是不可变的”。我该如何修改它?
回答by yuvi
You shouldn't use GET to send the username and password, it's bad practice (since it shows the information on the URL bar, and might pose a security risk). Instead, use POST. Also, I'm guessing you're trying to authenticate your users, and it seems like you're doing too much work (creating a new middleware) to deal with something that is completely built in, to take the example from the docs:
您不应该使用 GET 来发送用户名和密码,这是不好的做法(因为它会在 URL 栏上显示信息,并且可能会带来安全风险)。相反,使用 POST。另外,我猜您正在尝试对您的用户进行身份验证,而且您似乎做了太多工作(创建新的中间件)来处理完全内置的内容,以文档中的示例为例:
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
# Redirect to a success page.
else:
# Return a 'disabled account' error message
else:
# Return an 'invalid login' error message.
I myself really like using the login_required decorator, very simple to use. Hope that helps
我自己真的很喜欢使用login_required 装饰器,使用起来非常简单。希望有帮助
回答by Filip Dupanovi?
django.http.QueryDict
objects that are assigned to request.GET
and request.POST
are immutable.
django.http.QueryDict
分配给对象request.GET
和request.POST
是不可变的。
You can convert it to a mutable QueryDict
instance by copying it:
您可以QueryDict
通过复制将其转换为可变实例:
request.GET = request.GET.copy()
Afterwards you'll be able to modify the QueryDict
:
之后,您将能够修改QueryDict
:
>>> from django.test.client import RequestFactory
>>> request = RequestFactory().get('/')
>>> request.GET
<QueryDict: {}>
>>> request.GET['foo'] = 'bar'
AttributeError: This QueryDict instance is immutable
>>> request.GET = request.GET.copy()
<QueryDict: {}>
>>> request.GET['foo'] = 'bar'
>>> request.GET
<QueryDict: {'foo': 'bar'}>
This has been purposefully designed so that none of the application components are allowed to edit the source request data, so even creating a immutable QueryDict
again would break this design. I would still suggest that you follow the guidelines and assign additional request data directly on the request
object in your middleware, despite the fact that it might cause you to edit your sources.
这是有目的地设计的,因此任何应用程序组件都不允许编辑源请求数据,因此即使QueryDict
再次创建不可变的也会破坏这种设计。我仍然建议您遵循指南并直接在request
中间件中的对象上分配额外的请求数据,尽管这可能会导致您编辑源。
回答by laffuste
Remove immutability:
去除不变性:
if not request.GET._mutable:
request.GET._mutable = True
# now you can spoil it
request.GET['pwd'] = 'iloveyou'
Update
更新
The Django sanctioned way is: request.GET.copy().
Django 认可的方式是:request.GET.copy()。
According to the docs:
根据文档:
The QueryDicts at request.POST and request.GET will be immutable when accessed in a normal request/response cycle. To get a mutable version you need to use QueryDict.copy().
request.POST 和 request.GET 中的 QueryDicts 在正常请求/响应周期中访问时将是不可变的。要获得可变版本,您需要使用 QueryDict.copy()。
Nothing guarantees future Django versions will use _mutable. This has more chances to change than the copy()method.
没有什么可以保证未来的 Django 版本会使用_mutable。这比copy()方法有更多的机会改变。
回答by Mohideen bin Mohammed
request.GET._mutable = True
you need this.
你需要这个。
def func(request):
dic = request.GET
request.GET._mutable = True #to make it editable
username = dic.get("username")
request.GET.pop("pwd")
request.GET._mutable = False #make it False once edit done