Project does not recognize field

So. I’m creating a login page app. I have a registration page where you can add username, email and password, then you need to confirm your email through a code that’s send into your email

everything works well, including sending the email, but confirming the user code with the template input is giving me problems

first of all, I’ll show my views (won’t waste time with model because it’s a simple user model, with a boolean field called is_email_confirmed with default = False)

views.py

def createuser(request):
    form = MyUserCreationForm()
    confirmed = User.is_email_confirmed
    if request.method == 'POST':
        form = MyUserCreationForm(request.POST)
        if form.is_valid():     

            code = User.objects.make_random_password(length=6,allowed_chars='1234567890')

            user = form.save(commit=False)
            user.is_active = False 
            user.save()
            
            user.code = code
            usercode = user.code
            user.save()
            
            subject = 'Confirm your email' 
            confirmation_code = code
            message = f'Confirm your email with this code: {confirmation_code}'
            from_email = 'adryanftaborda@gmail.com'
            to_email = user.email
            send_mail(subject,message,from_email,[to_email])
            input_code = request.POST.get('verify_code')
            # NOT WORKING
            if input_code == usercode:
                confirmed = User.is_email_confirmed == True
                if confirmed:
                    user.is_active = True
                    user.save()
                return redirect('home')
            else:
                messages.error(request,'Wrong code.')
        else:
            messages.error(request,'An error occured during your registration')
    context = {'form':form}
    return render(request, 'signup.html', context)

as I said, everything seems to work, until here:

input_code = request.POST.get('verify_code')
            # NOT WORKING
            if input_code == usercode:
                confirmed = User.is_email_confirmed == True
                if confirmed:
                    user.is_active = True
                    user.save()
                return redirect('home')
            else:
                messages.error(request,'Wrong code.')

in my template, I have

{% block content%}


{% if form.is_valid == False %}

<div>
    <form method="POST" action="">
        {% csrf_token %}
        {{form.as_p}}

        <input type="submit" value="Register" />
    </form>
    
    <p>Already signed up?</p>
    <a href="{% url 'login' %}">Login</a>
</div>

{% else %}

<div>
    <form method="POST" action="{% url 'signup' %}">
        {% csrf_token %}
        Verification Code <input type="text" name="verify_code">
        <button type="submit">Submit</button>
    </form>
</div>

{% endif %}

{% endblock content %}

showing with prints the error, after digiting anything here (including the real code)…

Captura de tela 2024-02-28 200830

everything will back to the registration page with this error:

the user is also not active, as you can see in django model:

everything is working but this little piece of code

Each time you execute this block of code in the if form.is_valid():, you’re generating a new code.

        if form.is_valid():     

            code = User.objects.make_random_password(length=6,allowed_chars='1234567890')

      ...
            user.code = code
            usercode = user.code
            user.save()
        ...            
            input_code = request.POST.get('verify_code')
            # NOT WORKING
            if input_code == usercode:
                confirmed = User.is_email_confirmed == True

Whatever code was entered in the verify_code field is not going to be the same value that was generated when the MyUserCreationForm was submitted.

You need to rework your logic for this process - you’d be better off separating this functionality into separate views.

1 Like

so I could make
input_code = request.POST.get('verify_code') # NOT WORKING if input_code == usercode: confirmed = User.is_email_confirmed == True if confirmed: user.is_active = True user.save() return redirect('home') else: messages.error(request,'Wrong code.')
in another view, right? Is that what you’re saying?

Essentially, yes.

One view to create the user and send the confirmation code.

A different view to enter the code for confirmation.

1 Like

Excuse me, seems kinda late, but

aren’t django views independent? can I share infos of a view with another view? could cls help me in this case?

Precisely.

You have two different functions, performing two different operations. Therefore, you should have two separate views.

I’m asking how I will reference usercode = user.code in an other view (or any other variable)

Aren’t you saving it in the user object? If so, then that’s where you retrieve it from.

Well, I made the following view

def verifycode(request):
    user =  User.objects.all()
    input_code = request.POST.get('verify_code')
    
    if input_code == user.code:
        user.is_active = True
        user.save()
        return redirect('home')
    else:
        messages.error(request,'Wrong code.')
    return render(request, 'signup.html')

and the same problem returned.

OBS: This is my form

class   MyUserCreationForm(UserCreationForm):
    class Meta:
        model = User
        fields = ['username','email','password1','password2']

That’s retrieving all users as a queryset, not one specific user that you’re trying to test. That makes this:

a syntactically invalid statement.

Which user are you trying to compare this code for? That’s the user you need to retrieve from the User model.

The one that just created a user

if john_carl created a user with the email = johncarl123@gmail.com, then this user should receive an email and then confirm its email

Actually, you don’t know that.

Consider the following sequence:
Person A fills out the form.
Person B fills out the form.
Person A submits the code.
???

Keep in mind that the server does not keep a connection with the browser between requests. Each submit must be handled as an independent event.

Do you have any idea how could I do this email verification? any experience with that? it’s not an odd algorithm. The user will only be allowed to access its account after the email verification

I’m thinking about a ‘code’ field in my model and add a field in my form, but the problem is that these seems to be separate things. I have to verify if the form is valid, create the user then confirm the code.

The common process for doing something like this doesn’t include the user manually entering a code.

What I suggest you do is study the “Password reset” process (views and templates) to see a sample of how this type of mechanism works.

The short version is that when the user is created, a time-limited token is created that encodes the pk of that user. This token is sent as part of a url in a link in the email.

When the user clicks on that link, it takes them to the page that accepts the token as a parameter. That view then verifies the token as being valid, allowing the user to reset their password.

You can use this same process for this purpose.

1 Like

nice. I’ll use that.

I was thinking in that facebook/google way of creating a user (sending a little number code,
using it in the text bar, registering the user) but the way you described seems good as well