web-dev-qa-db-fra.com

Django, affiche ValidationError dans le template

Je crée une application d'enregistrement dans laquelle les utilisateurs peuvent s'inscrire en fournissant un nom d'utilisateur, une adresse électronique et un mot de passe. Ce que j'ai fait est de m'assurer que le champ email est unique (comme vous pouvez le voir dans le code ci-dessous). Mais je ne peux pas comprendre comment je peux afficher l'erreur si un utilisateur entre une adresse e-mail déjà utilisée.

Vue

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

Forme

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

Vous affichez le formulaire avec {{ form }} sur le modèle. Cela devrait lui-même afficher toutes les erreurs de validation par défaut, mais dans votre cas, vous êtes redirigé vers une autre page si le formulaire n'est pas valide. Vous ne pouvez donc jamais afficher les erreurs à moins de les transmettre avec les paramètres GET. Vous pouvez changer votre vue en ceci pour obtenir les erreurs sur la page d'inscription elle-même - 

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)

Comment cela fonctionne-t-il? Si la méthode de requête est POST, le formulaire est lancé avec les données POST, puis il est validé avec l'appel is_valid(), de sorte que l'objet de formulaire comporte désormais les messages d'erreur de validation s'il est invalide. S'il est valide, il est enregistré et redirigé. S'il n'est pas valide, cela concerne la partie args['form'] = form où l'objet de formulaire avec les messages d'erreur est défini sur le contexte, puis transmis au rendu.

Si la méthode de la requête n'est pas POST, un objet de formulaire sans données est instancié et transmis à render()

Maintenant, votre modèle devrait afficher tous les messages d'erreur juste en dessous de chaque champ s'il y a une erreur.

16
Bibhas Debnath

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>

** N'hésitez pas à copier le code et profitez-en! **

4
Deepak Kumar

Les vues basées sur les classes sont plus faciles.

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)

Les méthodes de nettoyage sont automatiques avec les formulaires et les messages restitués en tant que tels. Les vues basées sur les classes simplifient grandement la vie et votre code DRY.

0
Mikeec3