提问者:小点点

重置密码不相等时Django 2.0.8崩溃


在一个使用Django 2.0.8的Web项目中,我忘记了我的帐户密码。所以我决定使用“忘记密码”向导重置它。收到邮件并打开链接后,我到达了需要插入新密码(字段密码1)并再次确认(密码2)的表单。由于我写了两个不相等的密码(密码1=MyNewPass123),(密码2=MyNewPass12)犯了一个错误,应用程序因错误而崩溃:

ValueError at /auth/password/reset/confirm/<CODE>/set-password/

Need 2 values to unpack in for loop; got 17. 

<PATH>\lib\site-packages\django\template\defaulttags.py in render, line 202

所以我回去再试一次,这次使用了两个相同(有效)的密码,结果成功了。我重复了密码重置步骤,使用了一个新密码(同样是两个不相等的输入),但是它崩溃了。

搜索任何错误或相关问题没有返回任何结果。

这里的主要问题是什么:为什么ForNode在defaulttags.py中渲染收到这么多项目,只是因为两个不相等的值…对此有什么解决方案?

ForNode在defaulttags.py:

class ForNode(Node):
    child_nodelists = ('nodelist_loop', 'nodelist_empty')

    def __init__(self, loopvars, sequence, is_reversed, nodelist_loop, nodelist_empty=None):
        self.loopvars, self.sequence = loopvars, sequence
        self.is_reversed = is_reversed
        self.nodelist_loop = nodelist_loop
        if nodelist_empty is None:
            self.nodelist_empty = NodeList()
        else:
            self.nodelist_empty = nodelist_empty

    def __repr__(self):
        reversed_text = ' reversed' if self.is_reversed else ''
        return "<For Node: for %s in %s, tail_len: %d%s>" % \
            (', '.join(self.loopvars), self.sequence, len(self.nodelist_loop),
             reversed_text)

    def __iter__(self):
        yield from self.nodelist_loop
        yield from self.nodelist_empty

    def render(self, context):
        if 'forloop' in context:
            parentloop = context['forloop']
        else:
            parentloop = {}
        with context.push():
            try:
                values = self.sequence.resolve(context, True)
            except VariableDoesNotExist:
                values = []
            if values is None:
                values = []
            if not hasattr(values, '__len__'):
                values = list(values)
            len_values = len(values)
            if len_values < 1:
                return self.nodelist_empty.render(context)
            nodelist = []
            if self.is_reversed:
                values = reversed(values)
            num_loopvars = len(self.loopvars)
            unpack = num_loopvars > 1
            # Create a forloop value in the context.  We'll update counters on each
            # iteration just below.
            loop_dict = context['forloop'] = {'parentloop': parentloop}
            for i, item in enumerate(values):
                # Shortcuts for current loop iteration number.
                loop_dict['counter0'] = i
                loop_dict['counter'] = i + 1
                # Reverse counter iteration numbers.
                loop_dict['revcounter'] = len_values - i
                loop_dict['revcounter0'] = len_values - i - 1
                # Boolean values designating first and last times through loop.
                loop_dict['first'] = (i == 0)
                loop_dict['last'] = (i == len_values - 1)

                pop_context = False
                if unpack:
                    # If there are multiple loop variables, unpack the item into
                    # them.
                    try:
                        len_item = len(item)
                    except TypeError:  # not an iterable
                        len_item = 1
                    # Check loop variable count before unpacking
                    if num_loopvars != len_item:
                        raise ValueError(
                            "Need {} values to unpack in for loop; got {}. "
                            .format(num_loopvars, len_item),
                        )
                    unpacked_vars = dict(zip(self.loopvars, item))
                    pop_context = True
                    context.update(unpacked_vars)
                else:
                    context[self.loopvars[0]] = item

                for node in self.nodelist_loop:
                    nodelist.append(node.render_annotated(context))

                if pop_context:
                    # Pop the loop variables pushed on to the context to avoid
                    # the context ending up in an inconsistent state when other
                    # tags (e.g., include and with) push data to context.
                    context.pop()
        return mark_safe(''.join(nodelist))

password_reset_confirm. html

{% extends "base.html" %}
{% load crispy_forms_tags %}

{% block breadcrumb %}
{{ block.super }}
</h1>Password reset</h1>
{% endblock %}
{% block content %}
    {% if validlink %}
    <form method="post">
    {% if form.errors %}
    <div class="alert alert-danger">
        {% for key,value in form.error_messages %}
        {{ value }}<br />
        {% endfor %}
        {{ form.error_messages }}
    {% endif %}
    </div>
    {% csrf_token %}
    {{ form|crispy }}
    <button type="submit">Submit</button>
    </form>
    {% else %}
      <p>Wrong activation code</p>
    {% endif %}

{% endblock %}

跟踪回溯:

在内部35中的文件"\lib\site-包\django\core\handler\exception.py"。响应=get_response(请求)

_get_response158中的文件"\lib\site-包\django\core\handler\base.py"。响应=self。process_exception_by_middleware(e,请求)

文件"\lib\site-包\django\core\handler\base.py"在_get_response156. response=response.渲染()

在渲染106. self.content=self.rendered_content中的文件"\lib\site-包\django\模板\response.py"

文件"\lib\site-包\django\模板\response.py"在rendered_content83中。内容=模板。渲染(上下文,自我。_request)

在渲染61中的文件"\lib\site-包\django\模板\后端\django.py"。返回self.模板.渲染(上下文)

在渲染175中的文件"\lib\site-包\django\模板\base.py"。返回自己。_render(上下文)

文件"\lib\site-包\django\test\utils.py"在instrumented_test_render98中。

在渲染943. bit=node.render_annotated(上下文)中的文件"\lib\site-packs\django\temple\base.py"

文件"\lib\site-包\django\模板\base.py"在render_annotated910中。

在渲染155中的文件"\lib\site-packs\django\temet\loader_tags.py"返回compiled_parent_render(上下文)

文件"\lib\site-包\django\test\utils.py"在instrumented_test_render98中。

在渲染943. bit=node.render_annotated(上下文)中的文件"\lib\site-packs\django\temple\base.py"

文件"\lib\site-包\django\模板\base.py"在render_annotated910中。

渲染67中的文件"\lib\site-包\django\模板\loader_tags.py"。

在渲染943. bit=node.render_annotated(上下文)中的文件"\lib\site-packs\django\temple\base.py"

文件"\lib\site-包\django\模板\base.py"在render_annotated910中。

渲染314中的文件"\lib\site-包\django\模板\defaulttags.py"。返回nodelist.渲染(上下文)

在渲染943. bit=node.render_annotated(上下文)中的文件"\lib\site-packs\django\temple\base.py"

文件"\lib\site-包\django\模板\base.py"在render_annotated910中。

渲染314中的文件"\lib\site-包\django\模板\defaulttags.py"。返回nodelist.渲染(上下文)

在渲染943. bit=node.render_annotated(上下文)中的文件"\lib\site-packs\django\temple\base.py"

文件"\lib\site-包\django\模板\base.py"在render_annotated910中。

以渲染202…格式(num_loopvars,len_item)的文件"\lib\site-包\django\模板\defaulttags.py",

异常类型:ValueError at /auth/password/reset/confirm/MzAz/set-password/Exception Value:需要2个值才能解压for循环;有17个。


共1个答案

匿名用户

经过一步一步的努力,我设法找到了问题和解决方案。

问题出在我的password_reset_confirm. html

错误所在的代码:

{% if form.errors %}
    <div class="alert alert-danger">
# here it receives 17 values to unpack, but needs actually two (key, value)
    {% for key,value in form.**error_messages** %}
        {{ value }}<br />
    {% endfor %}
 {% endif %}

解决方案…

将“项目”放在表单末尾后。error_messages,我收到了一个有效的输出,没有错误。工作代码:

{% if form.errors %}
 <div class="alert alert-danger">
 {% for key, value in form.error_messages.items %}
     {{ value }}
 {% endfor %}
{% endif %}