在会话中存储 QueryDict 后无法进行 urlencode()

发布于 2024-11-29 22:49:16 字数 765 浏览 0 评论 0原文

我尝试将其发布到 django-users 组 ( http://groups. google.com/group/django-users/browse_thread/thread/8572d7f4075cfe0e )但没有回应。也许在这里我会得到更多的帮助。

我将 request.GET 存储在会话中:

request.session['query_string'] = request.GET

然后我在另一个页面中检索该值并尝试对该值进行 urlencode QueryDict:

context['query_string'] = request.session['query_string'].urlencode()

在我的上下文中,我得到了 python 的字符串表示形式 QueryDict 对象而不是预期的 key0=value0&key1=value1&... 细绳。

如果我将 urlencoded 字符串存储在 会话,当然一切正常:

request.session['query_string'] = request.GET.urlencode()

这是一个错误吗?

I tried to post this to django-users group ( http://groups.google.com/group/django-users/browse_thread/thread/8572d7f4075cfe0e ) but got no responses. Maybe here I will get more help.

I store request.GET in session:

request.session['query_string'] = request.GET

then I retrieve the value in another page and try to urlencode the
QueryDict:

context['query_string'] = request.session['query_string'].urlencode()

in my context I get the python's string representation of the
QueryDict object instead of the expected key0=value0&key1=value1&...
string.

If, instead of QueryDict, I store the urlencoded string in the
session, everything works of course:

request.session['query_string'] = request.GET.urlencode()

is it a bug?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧竹 2024-12-06 22:49:16

这是很古老的了,但是当我因为同样的问题而绊倒自己时,我想为那些通过搜索达到这个问题的人提供一个解决方案。核心问题是Django使用的默认序列化器会话数据:django.contrib.sessions.serializers.JSONSerializer。此序列化程序不知道与多个值关联的键(对于它们,应使用 QueryDict 的 getlist() 方法),这只会导致每个值的最后一个值正在使用的密钥。

有两种可能的解决方案:

  • 手动腌制和手动腌制。存储时解绑 request.GETrequest.POST 对象从会话中检索;
  • 或者,通过切换到 django.contrib.sessions.serializers.PickleSerializer 来pickle会话的整个数据。

This is very old, but as I stumbled myself because of the same issue, I want to offer a solution for those reaching this question via a search. The core issue is the default serializer Django uses for the session data: django.contrib.sessions.serializers.JSONSerializer. This serializer is not aware of keys associated with multiple values (for them, the getlist() method of QueryDict should be used), which results in only the last value for each key being used.

There are two possible solutions:

  • Either manually pickle & unpickle the request.GET or request.POST object when storing & retrieving from a session;
    • This will call the __getstate__() method of QueryDict, see also an old Django ticket.
  • Or, pickle the whole data of the session, by switching to the django.contrib.sessions.serializers.PickleSerializer.
青衫负雪 2024-12-06 22:49:16

这不是一个错误。如果您查看 QueryDict 定义(请参阅 https://github.com/django/django/blob/master/django/http/init.py),它明确表示它是不可变的,除非您创建副本它的。

为了演示这一点,这是我在 Python shell 中的内容,

>>> from django.http import QueryDict
>>> q1 = QueryDict('', mutable=False)
>>> q2 = QueryDict('', mutable=True)
>>> q1['next'] = '/a&b/'
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/kenny/Desktop/Kreybits/locker/python/lib/python2.7/site-packages/django/http/__init__.py", line 357, in __setitem__
    self._assert_mutable()
  File "/Users/kenny/Desktop/Kreybits/locker/python/lib/python2.7/site-packages/django/http/__init__.py", line 354, in _assert_mutable
    raise AttributeError("This QueryDict instance is immutable")
AttributeError: This QueryDict instance is immutable
>>> q2['next'] = '/a&b/'
>>> q2.urlencode()
'next=%2Fa%26b%2F'

默认情况下,mutable 参数设置为 False,并且由于 request.session['query_string'] = request.GET 首先将其初始化为一个空的 QueryDict,调用 urlencode() 仅返回一个空 str,而 request.session['query_string'] = request.GET.urlencode() 之所以有效,是因为您正在使用已使用适当的键/值初始化的 QueryDict。

This is not a bug. If you take a peek at the QueryDict definition (see https://github.com/django/django/blob/master/django/http/init.py), it says explicitly that it's immutable unless you create a copy of it.

To demonstrate this, here's what I have in my Python shell,

>>> from django.http import QueryDict
>>> q1 = QueryDict('', mutable=False)
>>> q2 = QueryDict('', mutable=True)
>>> q1['next'] = '/a&b/'
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/kenny/Desktop/Kreybits/locker/python/lib/python2.7/site-packages/django/http/__init__.py", line 357, in __setitem__
    self._assert_mutable()
  File "/Users/kenny/Desktop/Kreybits/locker/python/lib/python2.7/site-packages/django/http/__init__.py", line 354, in _assert_mutable
    raise AttributeError("This QueryDict instance is immutable")
AttributeError: This QueryDict instance is immutable
>>> q2['next'] = '/a&b/'
>>> q2.urlencode()
'next=%2Fa%26b%2F'

The mutable argument is set to False by default, and since request.session['query_string'] = request.GET initialized it to an empty QueryDict to begin with, calling urlencode() only returns you an empty str while the request.session['query_string'] = request.GET.urlencode() works because you're working with a QueryDict that has been initialized with the appropriate key/values.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文