如何让Django视图返回表单错误

时间:2022-03-02 20:21:28

This is my view:

这是我的看法:

def main_page(request):

    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            user = User.objects.create_user(
                username=form.clean_data['username'],
                password=form.clean_data['password1'],
                email=form.clean_data['email']
            )
        return HttpResponseRedirect('/')
    else:
        form = RegistrationForm()
        variables = {
            'form': form
        }
        return render(request, 'main_page.html', variables)

and this is my main_page.html:

这是我的main_page.html:

{% if form.errors %}
    <p>NOT VALID</p>
    {% for errors in form.errors %}
        {{ errors }}
    {% endfor %}
{% endif %}
<form method="post" action="/">{% csrf_token %}
    <p><label for="id_username">Username:</label>{{ form.username }}</p>
    <p><label for="id_email">Email Address:</label>{{ form.email }}</p>
    <p><label for="id_password">Password:</label>{{ form.password1 }}</p>
    <p><label for="id_retypePassword">Retype Password:</label>{{ form.password2 }}</p>
    <input type="hidden" name="next" />
    <input type="submit" value="Register" />
</form>

When I go to the url which uses the main_page view, it just displays the form. When I submit the form with errors (with blank fields and without a proper email address) it just redirects me to the same page and doesn't display any errors. It doesn't even say "NOT VALID".

当我转到使用main_page视图的url时,它只显示表单。当我提交包含错误的表单(包含空白字段且没有正确的电子邮件地址)时,它只是将我重定向到同一页面并且不显示任何错误。它甚至没有说“无效”。

When I change

当我改变

{% if form.errors %}

to

{% if not form.is_valid %}

it always says "NOT VALID" (even if it is the first time going to the url and even if I didn't submit anything yet).

它总是说“无效”(即使它是第一次进入网址,即使我还没有提交任何内容)。

This is my RegistrationForm:

这是我的RegistrationForm:

from django import forms
import re
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist

class RegistrationForm(forms.Form):
    username = forms.CharField(label='Username', max_length=30)
    email = forms.EmailField(label='Email')
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput())
    password2 = forms.CharField(label='Password (Again)', widget=forms.PasswordInput())

    def clean_password2(self):
        if 'password1' in self.cleaned_data:
            password1 = self.cleaned_data['password1']
            password2 = self.cleaned_data['password2']
            if password1 == password2:
                return password2
        raise forms.ValidationError('Passwords do not match.')

        def clean_username(self):
        username = self.cleaned_data['username']
        if not re.search(r'^\w+$', username): #checks if all the characters in username are in the regex. If they aren't, it returns None
            raise forms.ValidationError('Username can only contain alphanumeric characters and the underscore.')
        try:
            User.objects.get(username=username) #this raises an ObjectDoesNotExist exception if it doesn't find a user with that username
        except ObjectDoesNotExist:
            return username #if username doesn't exist, this is good. We can create the username
        raise forms.ValidationError('Username is already taken.')

2 个解决方案

#1


8  

It is redirecting you because you always return HttpResponseRedirect if the method is POST, even if the form is not vaild. Try this:

它正在重定向您,因为如果方法是POST,您总是返回HttpResponseRedirect,即使表单不是vaild。尝试这个:

def main_page(request):
    form = RegistrationForm()
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            user = User.objects.create_user(
                username=form.clean_data['username'],
                password=form.clean_data['password1'],
                email=form.clean_data['email']
            )
            return HttpResponseRedirect('/')        
    variables = {
        'form': form
    }
    return render(request, 'main_page.html', variables)

That way, the form instance, on which is_valid was called, is passed to the template, and it has a chance to display the errors. Only if the form is valid, the user is redirected. If you want to be fancy, add a message using the messages framework before redirecting.

这样,调用is_valid的表单实例将传递给模板,并且有机会显示错误。仅当表单有效时,才会重定向用户。如果您想要花哨,请在重定向之前使用消息框架添加消息。

If you want it a little bit more concise:

如果你想要它更简洁一点:

def main_page(request):
    form = RegistrationForm(request.POST or None)
    if form.is_valid():
        user = User.objects.create_user(
            username=form.clean_data['username'],
            password=form.clean_data['password1'],
            email=form.clean_data['email']
        )
        return HttpResponseRedirect('/')        
    variables = {
        'form': form
    }
    return render(request, 'main_page.html', variables)

#2


3  

Make your view something like this:

让你的观点像这样:

if form.is_valid():
    pass
    # actions
else:
    # form instance will have errors so we pass it into template
    return render(request, 'template.html', {'form': form})

And in the templates you can iterate over form.errors or simple:

在模板中,您可以迭代form.errors或简单:

{{ forms.as_p }}

#1


8  

It is redirecting you because you always return HttpResponseRedirect if the method is POST, even if the form is not vaild. Try this:

它正在重定向您,因为如果方法是POST,您总是返回HttpResponseRedirect,即使表单不是vaild。尝试这个:

def main_page(request):
    form = RegistrationForm()
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            user = User.objects.create_user(
                username=form.clean_data['username'],
                password=form.clean_data['password1'],
                email=form.clean_data['email']
            )
            return HttpResponseRedirect('/')        
    variables = {
        'form': form
    }
    return render(request, 'main_page.html', variables)

That way, the form instance, on which is_valid was called, is passed to the template, and it has a chance to display the errors. Only if the form is valid, the user is redirected. If you want to be fancy, add a message using the messages framework before redirecting.

这样,调用is_valid的表单实例将传递给模板,并且有机会显示错误。仅当表单有效时,才会重定向用户。如果您想要花哨,请在重定向之前使用消息框架添加消息。

If you want it a little bit more concise:

如果你想要它更简洁一点:

def main_page(request):
    form = RegistrationForm(request.POST or None)
    if form.is_valid():
        user = User.objects.create_user(
            username=form.clean_data['username'],
            password=form.clean_data['password1'],
            email=form.clean_data['email']
        )
        return HttpResponseRedirect('/')        
    variables = {
        'form': form
    }
    return render(request, 'main_page.html', variables)

#2


3  

Make your view something like this:

让你的观点像这样:

if form.is_valid():
    pass
    # actions
else:
    # form instance will have errors so we pass it into template
    return render(request, 'template.html', {'form': form})

And in the templates you can iterate over form.errors or simple:

在模板中,您可以迭代form.errors或简单:

{{ forms.as_p }}