简体   繁体   English

Django表单错误未显示在模板中

[英]Django Form errors not displaying in template

I'm using Django 1.11. 我正在使用Django 1.11。 I have a form with validation methods, which correctly raise ValidationErrors. 我有一个带有验证方法的表单,可以正确引发ValidationErrors。 When a form is submitted invalid, form.error_messages get filled as expected. 当表单提交无效时, form.error_messages会按预期填充。 However when I want to display errors in template, both form.non_field_errors and form.[field].errors are all blank. 但是,当我想在模板中显示错误时, form.non_field_errorsform.[field].errors都为空白。 Do I need to do anything extra to be able to use these? 我是否需要做任何其他事情才能使用这些功能? I'm kinda confused because this always "just worked" for me. 我有点困惑,因为这总是对我“起作用”。 I've read Django documentation on forms through and through as well as related SO questions and nothing helped. 我已经阅读了有关表单的Django文档以及相关的SO问题,但没有任何帮助。 Thanks for any advice. 感谢您的任何建议。

PS. PS。 I know I could use Django-included PasswordChangeForm and a respective view. 我知道我可以使用Django随附的PasswordChangeForm和相应的视图。 I have my reasons that are not obvious from the code below. 我的原因在下面的代码中并不明显。 Thanks. 谢谢。

forms.py 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 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)

template 模板

<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>

I would expect that {{ password_change_form.non_field_errors }} and {{ password_change_form.[field].errors }} will show something in the template, however they are blank. 我希望{{ password_change_form.non_field_errors }}{{ password_change_form.[field].errors }}将在模板中显示某些内容,但是它们为空白。 {{ password_change_form.error_messages }} shows the errors (as it does in a view too), but I actually never used this in a template and I guess it shouldn't be used this way. {{ password_change_form.error_messages }}显示了错误(也是如此,它在视图中也是如此),但是我实际上从未在模板中使用过此错误,并且我猜不应以这种方式使用它。

Figured it out. 弄清楚了。 Stupid mistake :) 愚蠢的错误:)

On the third row of views.py , I'm passing the data incorrectly. views.py的第三行中,我错误地传递了数据。 It should be done like this: 应该这样完成:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM