it-swarm.com.de

Django, zeige ValidationError in der Vorlage

Ich erstelle eine Registrierungs-App, in der sich Benutzer mit einem Benutzernamen, einer E-Mail-Adresse und einem Kennwort registrieren können. Was ich getan habe, ist sicherzustellen, dass das E-Mail-Feld eindeutig ist (wie Sie im Code unten sehen können). Ich kann jedoch nicht herausfinden, wie ich den Fehler anzeigen kann, wenn ein Benutzer eine E-Mail-Adresse eingibt, die bereits verwendet wird.

Aussicht

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

Bilden

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

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 %}
12
manosim

Sie zeigen das Formular mit {{ form }} auf der Vorlage. In diesem Fall sollten standardmäßig alle Validierungsfehler angezeigt werden. In Ihrem Fall werden Sie jedoch auf eine andere Seite umgeleitet, wenn das Formular ungültig ist. Sie können die Fehler also niemals anzeigen, wenn Sie die Fehler nicht mit den GET-Parametern übergeben. Sie können Ihre Ansicht ändern, um die Fehler auf der Anmeldeseite selbst zu erhalten. 

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)

Wie dies funktioniert ist, wenn die Anforderungsmethode POST ist, wird das Formular mit den Daten POST initiiert und dann mit dem Aufruf is_valid() validiert, sodass das Formularobjekt jetzt die Validierungsfehlermeldungen enthält, falls es ungültig ist. Wenn es gültig ist, wird es gespeichert und umgeleitet. Wenn es nicht gültig ist, kommt es zu dem args['form'] = form-Teil, in dem das Formularobjekt mit den Fehlernachrichten auf den Kontext gesetzt und dann an das Rendering übergeben wird.

Wenn die Anforderungsmethode nicht POST ist, wird ein Formularobjekt ohne Daten instanziiert und an render() übergeben. 

Jetzt sollte Ihre Vorlage alle Fehlermeldungen direkt unter jedem Feld anzeigen, wenn ein Fehler auftritt.

16
Bibhas Debnath

Warum nicht einfach so etwas machen:

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

Wenn der Benutzer bereits registriert ist, muss er einen Überprüfungsfehler auslösen. Wenn Sie dies nicht möchten, können Sie Folgendes tun:

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

Um die Formularfehler anzuzeigen, verwenden Sie form.is_valid(), um sicherzustellen, dass sie die Validierung bestehen. Django sagt Folgendes für benutzerdefinierte Validierungen :

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().

Dann können Sie in Ihrer Vorlage etwas wie {{ form.non_field_errors }} Usw. verwenden.

Siehe diesen Abschnitt in den Django docs, unter Using a form in a view Und Customizing the form template:
https://docs.djangoproject.com/en/dev/topics/forms/

5
antimatter

forms.py

from Django import forms

class RegistForm(forms.Form):

    name = forms.CharField(required=True)
    email = forms.EmailField(required=True)
    password = forms.CharField(required=True)

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)

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>

** Fühlen Sie sich frei, Code zu kopieren und zu genießen! **

4
Deepak Kumar

Klassenbasierte Ansichten sind einfacher.

from Django.views import generic
from .forms import RegistrationForm

class RegistrationView(generic.CreateView):
    template_class = 'registration/registration_form.html'
    form_class = RegistrationForm
    success_url = '/success/url'

    def form_valid(self, form):
        # add a log after save or whatever
        super(RegistrationView, self).form_valid(self, form)

Die sauberen Methoden werden automatisch mit Formularen und Nachrichten als solche gerendert. Klassenbasierte Ansichten machen das Leben viel einfacher und der Code DRYer.

0
Mikeec3