What is wrong with this procedure when saving a form?

Asked

Viewed 190 times

5

I have a registration form and I’m trying to save information on it.

When trying to register, it returns a form error saying the email already exists (even if registering different types of email). That is, it is saving before the checks whether the form is valid, but there is no instruction clarifying this.

class CadastroCreateView(CreateView):
    form_class = CadastroForm
    success_url = '/?cadastro=1'
    template_name = 'signup.html'
    model = Cadastro

    def get_context_data(self, **kwargs):
        context = super(CadastroCreateView, self).get_context_data(**kwargs)
        context.update({
            'estados':U.STATE_CHOICES,
            'culturas':Cultura.objects.all(),
            'interesses': Topico.objects.all(),
        })
        return context

    def post(self, request, *args, **kwargs):
        """
        Handles POST requests, instantiating a form instance and its inline
        formsets with the passed POST variables and then checking them for
        validity.
        """
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)


        if (form.is_valid()):
            return self.form_valid(form)
        else:
            return HttpResponse('oi')
            return self.form_invalid(form)

    def form_valid(self, form):
        """
        Called if all forms are valid. Creates a Recipe instance along with
        associated Ingredients and Instructions and then redirects to a
        success page.
        """
        self.object = form.save()
        u = authenticate(username=self.object.email, password=self.object.senha)
        authlogin(self.request, u)
        return redirect('conteudos:home')


    def form_invalid(self, form):
        """
        Called if a form is invalid. Re-renders the context data with the
        data-filled forms and errors.
        """
        return self.render_to_response(
            self.get_context_data(form=form)
        )
  • 1

    Dude, if you need to override a post, get, form_valid and invalid, review your idea of using class based view. This view can be greatly reduced if you go to Function based view.

  • 2

    And you can remove this implementation from your post and test, it’s not doing anything there. You can leave only form_valid

  • Right. Thank you very much.

1 answer

1


For "registration" of users we have the option to use the User framework of Django. This Fw includes the following models:

  • User: Model for users with main fields: username, password, email, first_name, last_name and is_active.

  • group: Group names for user categorization

  • permission: Self-explanatory

To answer the question, let’s develop an example in which we register users, taking advantage of this framework. To focus on the problem of email and make it simple, let’s just register "username" and your email.

I will report in this answer only the form, view and template development strategy. I have developed a complete example that you can download here.

First we will develop our form, which uses the User model of the Django authentication FW, as mentioned before, in this form we will include only the username and email.

from django import forms
from django.contrib.auth.models import User

class UserRegistrationForm(forms.ModelForm):

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

Now our view (in core/views.py)

from django.shortcuts import render, redirect
from .forms import UserRegistrationForm

def create_account(request):
    if request.method == 'POST':
        user_form = UserRegistrationForm(request.POST)

        if user_form.is_valid():
            new_user = user_form.save(commit=False)
            new_user.save()
            return render(request, 'core/register_done.html', {'new_user': new_user})
    else:
        user_form = UserRegistrationForm()
    return render(request, 'core/register.html', {'user_form': user_form})

The view is very simple. If a is "called" by a GET, it tries to render the Register.html template, if called by the POST and the form has been validated, it will try to render the register_done.html template, both from the core app, we will create them

core/register.html

{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
    <link href="{% static "css/base.css" %}" rel="stylesheet">
    <title>Cadastro de usuários com email</title>
</head>
<body>
    <h1>Criando uma conta</h1>
    <p>Digite os dados solicitados abaixo:</p>
    <form action="." method="post">
        {{ user_form.as_p }}
        {% csrf_token %}
        <p><input type="submit" value="Criar minha conta" </p>
    </form>
</body>
</html>

core/register_done.html

{% load staticfiles %}
<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <link href="{% static "css/base.css" %}" rel="stylesheet">
    <title>Cadastro de usuários com email</title>
</head>
<body>
    <h1>Registro Efetuado</h1>
    <p>Para criar outra conta <a href="{% url "create_account" %}"> Clique aqui</a>  </p>
</body>
</html>

With this Cvoce can register emails in a model, through a form. If you want you can extend the Django User to another model, such as a Profile. To test the complete code of this solution, clone the repository in git-hub

Browser other questions tagged

You are not signed in. Login or sign up in order to post.