Django, mostra ValidationError nel modello

Creare una registrazione app, dove gli utenti possono registrarsi fornendo un nome utente, email e password. Quello che ho fatto è fare in modo che il campo email è unico(come si può vedere nel codice riportato di seguito). Ma io non riesco a capire come posso mostrare l’errore nel caso in cui un utente inserisce un indirizzo e-mail è già in uso.

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

Forma

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 %}
InformationsquelleAutor manosim | 2014-03-18

 

4 Replies
  1. 17

    Si sta mostrando il modulo con {{ form }} sul modello. Che di per sé dovrebbe mostrare tutti gli errori di validazione per impostazione predefinita, ma nel tuo caso, vuoi reindirizzare ad un’altra pagina se il modulo non è valido. Quindi non si può mai mostrare gli errori a meno che non si passano gli errori con i parametri GET. Si potrebbe cambiare la tua visione di questo per ottenere gli errori di iscrizione pagina –

    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)

    Come funziona, se il metodo di richiesta è POSTA, il modulo viene avviato con i dati del POST, quindi è convalidato con la is_valid() chiamata, in modo che il modulo ha l’messaggi di errore di validazione se è valido. Se è valido, viene salvato e si viene reindirizzati. Se non valido, si tratta di args['form'] = form parte in cui l’oggetto form con i messaggi di errore è impostato per il contesto e poi passati per il rendering.

    Se il metodo di richiesta non è POST, quindi un oggetto form con i dati non viene creata un’istanza e passato a render().

    Ora il tuo modello dovrebbe mostrare tutti i messaggi di errore appena al di sotto di ogni campo, se c’è qualche errore.

    • Sto avendo lo stesso errore, ma non capisco come args giocare in questo. Perché args anche non esistere? Non è usato nel modello.
  2. 7

    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>

    ** Sentitevi liberi di copiare il codice e godere! **

  3. 5

    Perché non basta fare qualcosa di simile a questo:

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

    Se l’utente è già registrato, fare sollevare un errore di convalida. Se non si vuole fare questo, si può fare qualcosa di simile:

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

    Per visualizzare il modulo di errori, è possibile utilizzare form.is_valid() per assicurarsi che si passa la validazione. Django dice il seguente per personalizzato convalide:

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

    Quindi nel modello è possibile utilizzare qualcosa come {{ form.non_field_errors }}, etc.

    Vedere questa sezione in Django docs, sotto Using a form in a view e Customizing the form template:

    https://docs.djangoproject.com/en/dev/topics/forms/

    • Grazie per la risposta veloce! Il fatto è che io non riesco a gestire il “ValidationError” per visualizzare il messaggio nel modello. cioè({% if forma.errori %}…)
    • Ah è in django docs. Si può fare form.errors e altri, se si utilizza form.is_valid() nel vostro punto di vista. Vedi la mia risposta aggiornata.
    • Dovrebbe mostrare in {% form.errors %} se si verifica la convalida, a vostro parere, utilizzando form.is_valid(). Sono curioso, quindi, keep me posted se funziona.
    • Il fatto è che io uso la “forma.is_valid()” nel mio views.py file. Lo si può trovare qui pastebin.com/068mAnWh .
    • Ho trovato la risposta qui: link ho aggiornato la mia risposta. È necessario chiamare add_error() e non_field_errors()
    • Per essere onesti, ho provato ma non riesco a capire dove posizionarlo nel mio codice. Cercato di trovare alcuni esempi che uso anch’io, ma niente. Qualche possibilità che tu possa aiutarmi ulteriormente?
    • Prova a mettere quelli da visualizzare e salvare in una variabile. Poi farlo passare come una variabile nel contesto quando si esegue render(request, 'url', context), e provare a stampare la variabile. Fammi sapere come va.
    • Hmm. Ho fatto questo link e anche aggiunto {{ form.non_field_errors }}, ma ancora niente.
    • Cambiare form.non_field_errors() a qualcosa come custom_error = form.non_field_errors(), e quindi di creare qualcosa di simile args['custom']=custom_error e accesso {% custom %}
    • Beh, ho provato ma purtroppo non ha avuto risultati. Penso che devo trovare un’alternativa così la volontà di cercare qualche tutorial o un app per questo. Grazie mille per il vostro aiuto!! Davvero apprezzato!
    • Ah bene :/ Una rapida soluzione sarebbe passare di errore personalizzato come un messaggio in contesto quando si esegue il rendering. O utilizzare i messaggi flash…

  4. 0

    Classe visualizzazioni sono più facili.

    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)

    Pulito metodi automatici con le forme e i messaggi di rendering, come tale,
    classe visualizzazioni di rendere la vita molto più facile, e il tuo codice Asciugatrice.

Lascia un commento