Django,在模板中显示ValidationError

man*_*sim 19 forms email django unique validationerror

我创建了一个注册应用程序,用户可以在其中注册提供用户名,电子邮件和密码.我所做的是确保电子邮件字段是唯一的(如下面的代码所示).但是,如果用户输入已在使用的电子邮件地址,我无法弄清楚如何显示错误.

视图

from django.shortcuts import render
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf

from forms import RegistrationForm

# Create your views here.
def register_user(request):
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('../../membership/register_success')
        else:
            return HttpResponseRedirect('../../membership/register_failed')

    args = {}
    args.update(csrf(request))

    args['form'] = RegistrationForm()

    return render(request,'registration/registration_form.html', args)

def register_success(request):
    return render_to_response('registration/registration_success.html')

def register_failed(request):
    return render_to_response('registration/registration_failed.html')
Run Code Online (Sandbox Code Playgroud)

形成

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from django.utils.translation import ugettext_lazy as _

    # forms.py
    class RegistrationForm(UserCreationForm):
        email = forms.EmailField(required=True)

        class Meta:
            model = User
            fields = ('username', 'email', 'password1', 'password2')

        def clean_email(self):
            email = self.cleaned_data.get('email')
            username = self.cleaned_data.get('username')

            if email and User.objects.filter(email=email).exclude(username=username).count():
                raise forms.ValidationError(_("This email address is already in use. Please supply a different email address."))
            return email

        def save(self, commit=True):
            user = super(RegistrationForm, self).save(commit=False)
            user.email = self.cleaned_data['email']
            if commit:
                user.save()
            return user
Run Code Online (Sandbox Code Playgroud)

registration.html

    {% extends "base.html" %}
    {% block title %}Registration{% endblock %}

    {% block content %}

            <h1>Registration</h1>

            {% if form.errors %}
            <h1>ERRORRRRRR same email again???</h1>
            {% endif %}

            {% if registered %}
            <strong>thank you for registering!</strong>
            <a href="../../">Return to the homepage.</a><br />
            {% else %}
            <strong>register here!</strong><br />

            <form method="post" action="/membership/register/">{% csrf_token %}
                {{ form }}
                <input type="submit" name="submit" value="Register" />
            </form>
            {% endif %}

    {% endblock %}
Run Code Online (Sandbox Code Playgroud)

Bib*_*ath 17

您正在{{ form }}模板上显示表单.默认情况下,这本身应该显示所有验证错误,但在您的情况下,如果表单无效,您将重定向到其他页面.因此,除非使用GET参数传递错误,否则永远不会显示错误.您可以将视图更改为此以在注册页面本身上获取错误 -

def register_user(request):
    args = {}
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('../../membership/register_success')
    else:
        form = RegistrationForm()
    args['form'] = form

    return render(request,'registration/registration_form.html', args)
Run Code Online (Sandbox Code Playgroud)

这是如何工作的,如果请求方法是POST,表单将使用POST数据启动,然后通过is_valid()调用进行验证,因此表单对象现在具有验证错误消息(如果它无效).如果它有效,则保存并重定向.如果无效,则会将args['form'] = form带有错误消息的表单对象设置为上下文然后传递给render的部分.

如果请求方法不是POST,则实例化并传递没有数据的表单对象render().

现在,如果有任何错误,您的模板应该在每个字段下方显示所有错误消息.

  • 我遇到了同样的错误,但我不明白“args”是如何发挥作用的。为什么 args 存在?模板中未使用它。 (2认同)

小智 7

表格

from django import forms

class RegistForm(forms.Form):

    name = forms.CharField(required=True)
    email = forms.EmailField(required=True)
    password = forms.CharField(required=True)
Run Code Online (Sandbox Code Playgroud)

views.py

from django.shortcuts import render
from django.views.generic import TemplateView
import forms

class Register(TemplateView):

    def get(self, request):
        return render(request, 'register.html', {})

    def post(self, request):
        form = forms.RegistForm(request.POST)
        if form.is_valid():
            print(1)
        else:
            print(form.errors)
        content = {'form':form};
        return render(request, 'register.html', content)
Run Code Online (Sandbox Code Playgroud)

register.html

    <form action="{% url 'register' %}" method="post">

        {% csrf_token %}

        <fieldset>
          <label for="name">Name:</label>
          <input type="text" id="name" name="name" value="">
          {{ form.errors.name }}

          <label for="mail">Email:</label>
          <input type="text" id="mail" name="email">
          {{ form.errors.email }}

          <label for="password">Password:</label>
          <input type="password" id="password" name="password">
          {{ form.errors.password }}
        </fieldset>

        <button type="submit">Sign Up</button>

        <p class="message">Already registered? <a href="{% url 'login' %}">Login</a></p>

    </form>
Run Code Online (Sandbox Code Playgroud)

**随意复制代码并享受!**


ant*_*ter 5

为什么不做这样的事情:

...
if User.objects.filter(email=email):
    raise forms.ValidationError(_("This email address is already in use. Please supply a different email address."))
return email
...
Run Code Online (Sandbox Code Playgroud)

如果用户已经注册,则引发验证错误。如果您不希望它这样做,则可以执行以下操作:

...
email_exists = User.objects.filter(email=email):
if email_exists and email_exists.username != username:
    raise forms.ValidationError(_("This email address is already in use. Please supply a different email address."))
return email
...
Run Code Online (Sandbox Code Playgroud)

要显示表单错误,请使用form.is_valid()以确保其通过验证。Django对自定义验证说以下内容:

Note that any errors raised by your Form.clean() override will not be associated with any field in particular. They go into a special “field” (called __all__), which you can access via the non_field_errors() method if you need to. If you want to attach errors to a specific field in the form, you need to call add_error().

然后,您可以在模板中使用{{ form.non_field_errors }},等等。

见Django文档这一节中,下Using a form in a viewCustomizing the form template
https://docs.djangoproject.com/en/dev/topics/forms/