首页 > 解决方案 > Django request.user.is_authenticated 引发字典更新序列元素#0 的长度为 X;2 是必需的

问题描述

每次我的代码到达某一行时,它似乎都会引发dictionary update sequence element #0 has length X; 2 is required错误。X 的值可以改变,但在调用它时几乎总是会引发错误:

if request.user.is_authenticated

python 3.6.7django 2.1.7

这是错误堆栈

    Traceback:

File "/path/to/venv/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/path/to/venv/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "/path/to/venv/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "./playerdata/api/tokens.py" in token_queries
  87.     if request.user.is_authenticated:

File "/path/to/venv/lib/python3.6/site-packages/django/utils/functional.py" in inner
  213.             self._setup()

File "/path/to/venv/lib/python3.6/site-packages/django/utils/functional.py" in _setup
  347.         self._wrapped = self._setupfunc()

File "/path/to/venv/lib/python3.6/site-packages/django/contrib/auth/middleware.py" in <lambda>
  24.         request.user = SimpleLazyObject(lambda: get_user(request))

File "/path/to/venv/lib/python3.6/site-packages/django/contrib/auth/middleware.py" in get_user
  12.         request._cached_user = auth.get_user(request)

File "/path/to/venv/lib/python3.6/site-packages/django/contrib/auth/__init__.py" in get_user
  189.             user = backend.get_user(user_id)

File "/path/to/venv/lib/python3.6/site-packages/django/contrib/auth/backends.py" in get_user
  98.             user = UserModel._default_manager.get(pk=user_id)

File "/path/to/venv/lib/python3.6/site-packages/django/db/models/manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/path/to/venv/lib/python3.6/site-packages/django/db/models/query.py" in get
  390.         clone = self.filter(*args, **kwargs)

File "/path/to/venv/lib/python3.6/site-packages/django/db/models/query.py" in filter
  844.         return self._filter_or_exclude(False, *args, **kwargs)

File "/path/to/venv/lib/python3.6/site-packages/django/db/models/query.py" in _filter_or_exclude
  862.             clone.query.add_q(Q(*args, **kwargs))

File "/path/to/venv/lib/python3.6/site-packages/django/db/models/sql/query.py" in add_q
  1263.         clause, _ = self._add_q(q_object, self.used_aliases)

File "/path/to/venv/lib/python3.6/site-packages/django/db/models/sql/query.py" in _add_q
  1289.                 joinpromoter.add_votes(needed_inner)

File "/path/to/venv/lib/python3.6/site-packages/django/db/models/sql/query.py" in add_votes
  2171.         self.votes.update(votes)

File "/usr/lib/python3.6/collections/__init__.py" in update
  620.                     super(Counter, self).update(iterable) # fast path when counter is empty

Exception Type: ValueError
Exception Value: dictionary update sequence element #0 has length 9; 2 is required

request.user.is_authenticated 周围的代码:

def token_queries(request):    
    data = None
    if request.user.is_authenticated:
        data = login_required(request)
    if data is None:
        data = anonymous(request)
    return json_response(data)

编辑:附加信息

我必须准确地说,这个错误每天触发一次,接近我在网站上的活动高峰期。一旦触发,它将在停止前持续发送垃圾邮件几个小时。它也不仅发生在 tokens.py 文件中,而且几乎发生在用户试图被访问的代码中的任何地方。

更新:与负载平衡有关

该错误似乎与负载平衡有关。当错误开始发送垃圾邮件时,它一次只会发生在一个 LB 节点上。我发现从负载均衡器中取出一个节点会阻止它发生。它甚至不必是发生错误的节点!如果我将两个节点都重新打开,则错误会立即再次触发。

例如:

阻止它的唯一方法是重新启动托管发生错误的节点的机器。

为 LB 添加 1 小时粘性并不能解决问题。

我在 AWS 服务器上通过 Nginx 运行 Django。

标签: pythondjango

解决方案


我可以在您的错误跟踪中识别出异常行:

File "/usr/lib/python3.6/collections/__init__.py" in update
  620.                     super(Counter, self).update(iterable) # fast path when counter is empty 

在正常情况下,永远不应达到此线。如果您查看“collections/__init__.py”中的源代码

if isinstance(iterable, Mapping):
    ...
        super(Counter, self).update(iterable) # fast path when counter is empty

该变量是从 函数中的变量iterable传递下来的。其类型应始终为. 因此,永远不应该。needed_inner_add_q<class 'set'>isinstance(iterable, Mapping)True

正如您所说,您没有使用 custom AUTH_USER_MODEL。因此,最合理的解释是 Nginx WSGI python 实现中的一个隐藏错误(可能与负载平衡有关)。


推荐阅读