Ravindra Dahal
Ravindra Dahal

Reputation: 3

Django Form does not show up until it's submitted

I made a form in Django, but it's not showing up before it's been submitted.

The forms.py looks like this

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


class SignUpForm(UserCreationForm):
    email = forms.EmailField(
        max_length=100, help_text='Required. Add a valid email address!!', label='Email')
    name = forms.CharField(max_length=50, label='Name')
    password1 = forms.PasswordInput()
    password2 = forms.PasswordInput()

    class Meta:
        model = User

        fields = ('email', 'name', 'password1', 'password2')

        # email = forms.EmailField(max_length=100, help_text='required')


The views.py file looks like this:

    from django.contrib.auth import get_user_model
from .tokens import account_activation_token
from .forms import SignUpForm
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes
from django.template.loader import render_to_string
from django.http import HttpResponse
from django.core.mail import EmailMessage
from django.contrib.sites.shortcuts import get_current_site
from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth.models import User
from dotenv import load_dotenv, find_dotenv
from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate

# Create your views here.

from productapp.models import User

UserModel = get_user_model()
# Create your views here.


def signup(request):
    print(request.POST)
    if request.method == 'GET':
        return render(request, 'authentication/register.html')
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        print(form.is_valid())
        if form.is_valid():
            user = form.save(commit=False)
            user.normaluser = False
            user.save()
            current_site = get_current_site(request)
            mail_subject = 'Activate your account.'
            message = render_to_string('authentication/email_template.html', {
                'user': user,
                'domain': current_site.domain,
                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                'token': default_token_generator.make_token(user),
            })
            to_email = form.cleaned_data.get('email')
            email = EmailMessage(
                mail_subject, message, to=[to_email]
            )
            email.send()
            return HttpResponse('Please confirm your email address to complete the registration')
    else:
        form = SignUpForm()
    return render(request, 'authentication/register.html', {'form': form})


def activate(request, uidb64, token):
    try:
        uid = urlsafe_base64_decode(uidb64).decode()
        user = UserModel._default_manager.get(pk=uid)
    except(TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None
    if user is not None and default_token_generator.check_token(user, token):
        user.is_active = True
        user.save()
        return HttpResponse('Thank you for your email confirmation. Now you can login your account.')
    else:
        return HttpResponse('Activation link is invalid!')


def register(request):
    context = {}
    if request.POST:
        form = SignUpForm(request.POST)
        if form.is_valid():
            form.save()
            email = form.cleaned_data.get('email')
            raw_password = form.cleaned_data.get('password1')
            account = authenticate(email=email, password=raw_password)
            login(request, account)
            return redirect('login')
        else:
            context['form'] = form
    else:
        form = SignUpForm()
        context['form'] = form
    return render(request, 'authentication/register.html', context)

And this is what the template looks like.

   {% extends 'index.html' %}
<!-- {%load crispy_forms_tags %} -->

{% block content %}
<div style="display:flex;justify-content: center;flex-direction: row;">

    <form method="post">
        {% csrf_token %}
        <center>
            <h3>Sign Up</h3>
        </center>
        <!-- {{form|crispy}} -->
        <!-- {{form.as_p}} -->
        {% for field in form %}
        <p>
            {{field.name.capitalize}}
            {{ field }}
            {% for error in field.errors %}
        <p style="color: red">{{ error }}</p>
        {% endfor %}
        </p>
        {% endfor %}

        <center><button class='btn btn-primary' type="submit">Sign up</button>
        </center>
    </form>
</div>

{% endblock %}

This is what the url looks like when you first visit it. Picture of the form

And this is what it looks like after submission. Picture of the form after submission

Upvotes: 0

Views: 75

Answers (2)

Mojtaba Kamyabi
Mojtaba Kamyabi

Reputation: 3600

it seems your first if statement in signup function is redundant.

if request.method == 'GET':
        return render(request, 'authentication/register.html')

you don't send form variable to the template in these lines. this is why form is not shown in the template. just remove it. you already send your form in the last line of your function:

return render(request, 'authentication/register.html', {'form': form})

Upvotes: 2

Mugoya Dihfahsih
Mugoya Dihfahsih

Reputation: 425

do this in your views.py

from django.contrib.auth import get_user_model
from .tokens import account_activation_token
from .forms import SignUpForm
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes
from django.template.loader import render_to_string
from django.http import HttpResponse
from django.core.mail import EmailMessage
from django.contrib.sites.shortcuts import get_current_site
from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth.models import User
from dotenv import load_dotenv, find_dotenv
from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate

# Create your views here.

from productapp.models import User

UserModel = get_user_model()
# Create your views here.


def signup(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            user = form.save(commit=False)
            user.normaluser = False
            user.save()
            current_site = get_current_site(request)
            mail_subject = 'Activate your account.'
            message = render_to_string('authentication/email_template.html', {
                'user': user,
                'domain': current_site.domain,
                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                'token': default_token_generator.make_token(user),
            })
            to_email = form.cleaned_data.get('email')
            email = EmailMessage(
                mail_subject, message, to=[to_email]
            )
            email.send()
            return HttpResponse('Please confirm your email address to complete the registration')

        #what should the function return if the form has errors
    else:
        form = SignUpForm()
        return render(request, 'authentication/register.html', {'form': form})

Upvotes: 0

Related Questions