Django表单错误未显示在模板

时间:2017-05-20 22:37:21

标签: python django django-forms django-templates django-views

我正在使用Django 1.11。我有一个带有验证方法的表单,它正确地引发了ValidationErrors。如果提交的表单无效,form.error_messages会按预期填写。但是,当我想在模板中显示错误时,form.non_field_errorsform.[field].errors都是空白的。我是否需要做任何额外的事情才能使用这些?我有点困惑,因为这对我来说总是“有效”。我已经阅读了关于表格的Django文档,以及相关的SO问题,没有任何帮助。谢谢你的任何建议。

PS。我知道我可以使用包含Django的PasswordChangeForm和相应的视图。我的原因在下面的代码中并不明显。感谢。

forms.py

class PasswordChangeForm(forms.Form):
    prefix = 'password_change'
    error_messages = {
        'password_mismatch': "The two password fields didn't match.",
        'password_incorrect': "Your old password was entered incorrectly. Please enter it again.",
    }
    old_password = forms.CharField(
        label="Old password",
        strip=False,
    )
    new_password1 = forms.CharField(
        label="New password",
        strip=False,
        help_text=password_validation.password_validators_help_text_html(),
    )
    new_password2 = forms.CharField(
        label="New password repeated",
        strip=False,
    )

    field_order = ['old_password', 'new_password1', 'new_password2']

    def __init__(self, user, *args, **kwargs):
        self.user = user
        super().__init__(*args, **kwargs)

    def clean_old_password(self):
        """
        Validate that the old_password field is correct.
        """
        old_password = self.cleaned_data["old_password"]
        if not self.user.check_password(old_password):
            raise forms.ValidationError(
                self.error_messages['password_incorrect'],
                code='password_incorrect',
            )
        return old_password

    def clean_new_password2(self):
        password1 = self.cleaned_data.get('new_password1')
        password2 = self.cleaned_data.get('new_password2')
        if password1 and password2:
            if password1 != password2:
                raise forms.ValidationError(
                    self.error_messages['password_mismatch'],
                    code='password_mismatch',
                )
        password_validation.validate_password(password2, self.user)
        return password2

    def save(self, commit=True):
        password = self.cleaned_data["new_password1"]
        self.user.set_password(password)
        if commit:
            self.user.save()
        return self.user

views.py

def profile(request):
    if request.method == 'POST' and 'password_change-submit' in request.POST:
        password_change_form = PasswordChangeForm(request.POST)
        if password_change_form.is_valid():
            pass
        else:
            # for debugging purposes ... this prints errors to the console as expected
            print(password_change_form.error_messages)
    else:
        password_change_form = PasswordChangeForm(request.user)

    context = {'password_change_form': password_change_form}

    return render(request, 'profile.html', context)

模板

<form action="{% url 'profile' %}" method="POST">
    {% csrf_token %}
    {{ password_change_form.non_field_errors }}
    {{ password_change_form.error_messages }}  <-- for debugging purposes, this actually shows something
    <div class="form-group">
        {{ password_change_form.old_password.errors }}
        <label for="{{ password_change_form.old_password.id_for_label }}">{{ password_change_form.old_password.label }}</label>
        <input type="password" class="form-control" id="{{ password_change_form.old_password.id_for_label }}" name="{{ 
password_change_form.old_password.html_name }}" placeholder="{{ password_change_form.old_password.label }}">
    </div>
    <div class="form-group">
        {{ password_change_form.new_password1.errors }}
        <label for="{{ password_change_form.new_password1.id_for_label }}">{{ password_change_form.new_password1.label }}</label>
        <input type="password" class="form-control" id="{{ password_change_form.new_password1.id_for_label }}" name="{{ 
password_change_form.new_password1.html_name }}" placeholder="{{ password_change_form.new_password1.label }}">
    </div>
    <div class="form-group">
        {{ password_change_form.new_password2.errors }}
        <label for="{{ password_change_form.new_password2.id_for_label }}">{{ password_change_form.new_password2.label }}</label>
        <input type="password" class="form-control" id="{{ password_change_form.new_password2.id_for_label }}" name="{{ 
password_change_form.new_password2.html_name }}" placeholder="{{ password_change_form.new_password2.label }}">
    </div>
    <input type="submit" class="btn btn-primary" name="password_change-submit" value="Change password">
</form>

我希望{{ password_change_form.non_field_errors }}{{ password_change_form.[field].errors }}会在模板中显示一些内容,但它们是空白的。 {{ password_change_form.error_messages }}显示错误(就像在视图中一样),但我实际上从未在模板中使用过这个错误,我想它不应该以这种方式使用。

1 个答案:

答案 0 :(得分:0)

想出来。愚蠢的错误:)

views.py 的第三行,我错误地传递了数据。它应该这样做:

password_change_form = PasswordChangeForm(user=request.user, data=request.POST)