DEV Community

Cover image for Creating The Sign Up Page Part I
Hana Belay
Hana Belay

Posted on

Creating The Sign Up Page Part I

Hello, glad to see you here again. In today's part of the series, we are going to create the sign up page.


Okay to create users we need a model right, we need to define what kind of attributes users should have. Django comes with a built in User model whose primary attributes are:

  • username
  • password
  • email
  • first_name
  • last_name

If we want our users to have more attributes than this built in model gives us, there are a couple of ways to do that and we will see one way in the future when we create a user profile. But for now we are using the Django User model as it is so we should be fine.

Next, we need a form that will be displayed to the users, validate the data and save it to the database. Luckily we don't have to reinvent the wheel because Django has a built in easy to use UserCreationForm.

UserCreationForm is a form that creates a user, with no privileges, from the given username and password. - docs

  • Looks good, but what if we want to include extra fields in our form and get other information about the user upon sign up?

For that, we can just simply extend the built in model form and add more fields. I'm going to add email, firstname, and lastname of the user.

Don't forget that the fields am adding are already in the User model

Create forms.py module inside the users app and first let's import the necessary dependencies.

forms.py

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
Enter fullscreen mode Exit fullscreen mode
  • Forms in Django is a class whose fields map to HTML form elements.
  • forms class has different fields for handling different types of data. For example, CharField, DateField... Check out the docs here to look at more of these fields.
  • These form fields are represented to the user as an HTML widget (Widgets render HTML form elements) therefore unless we explicitly specify the widget for our form field, Django will use default widgets which may not look that good.
  • By overriding the default widget for the form field, we can bootstrapify our form fields.

forms.py

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

class RegisterForm(UserCreationForm):
    # fields we want to include and customize in our form
    first_name = forms.CharField(max_length=100,
                                 required=True,
                                 widget=forms.TextInput(attrs={'placeholder': 'First Name',
                                                               'class': 'form-control',
                                                               }))
    last_name = forms.CharField(max_length=100,
                                required=True,
                                widget=forms.TextInput(attrs={'placeholder': 'Last Name',
                                                              'class': 'form-control',
                                                              }))
    username = forms.CharField(max_length=100,
                               required=True,
                               widget=forms.TextInput(attrs={'placeholder': 'Username',
                                                             'class': 'form-control',
                                                             }))
    email = forms.EmailField(required=True,
                             widget=forms.TextInput(attrs={'placeholder': 'Email',
                                                           'class': 'form-control',
                                                           }))
    password1 = forms.CharField(max_length=50,
                                required=True,
                                widget=forms.PasswordInput(attrs={'placeholder': 'Password',
                                                                  'class': 'form-control',
                                                                  'data-toggle': 'password',
                                                                  'id': 'password',
                                                                  }))
    password2 = forms.CharField(max_length=50,
                                required=True,
                                widget=forms.PasswordInput(attrs={'placeholder': 'Confirm Password',
                                                                  'class': 'form-control',
                                                                  'data-toggle': 'password',
                                                                  'id': 'password',
                                                                  }))

    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'username', 'email', 'password1', 'password2']
Enter fullscreen mode Exit fullscreen mode
  • I added an id for the password fields because we are gonna use a plugin that shows password hide/show icon - you know that weird looking eye icon. But more on that later when we create the template.
  • Under Meta class we can create the link between our model's fields and the different fields we want to have in our form(order matters).

Alright! Let's head over to views.py and use the form we just created.

Here I'm using class-based view to handle the register form. Check the docs for more info about what am using.

views.py

from django.shortcuts import render, redirect 
from django.contrib import messages
from django.views import View

from .forms import RegisterForm


class RegisterView(View):
    form_class = RegisterForm
    initial = {'key': 'value'}
    template_name = 'users/register.html'

    def get(self, request, *args, **kwargs):
        form = self.form_class(initial=self.initial)
        return render(request, self.template_name, {'form': form})

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)

        if form.is_valid():
            form.save()

            username = form.cleaned_data.get('username')
            messages.success(request, f'Account created for {username}')

            return redirect(to='/')

        return render(request, self.template_name, {'form': form})
Enter fullscreen mode Exit fullscreen mode
  • First by overriding the form_class attribute, we are able to tell django which form to use, template_name -> the template we want django to look for
  • If the request is get, it creates a new instance of an empty form.
  • If the request is post, -- It creates a new instance of the form with the post data. Then checks if the form is valid or not by calling the form.is_valid() method. -- Then if the form is valid, process the cleaned form data and save the user to our database.
  • To let the user know that his/her account is successfully created, we can generate a flash message and display his/her username to the page they are getting redirected to(home page).

Next let's map our urlpatterns to our register view.

users/urls.py

from django.urls import path
from .views import home, RegisterView  # Import the view here

urlpatterns = [
    path('', home, name='users-home'),
    path('register/', RegisterView.as_view(), name='users-register'),  # This is what we added
]
Enter fullscreen mode Exit fullscreen mode

This is getting kinda long so, we will create the template in the next part.

Thanks for your time, you can find the finished app in github.

Feel free to ask, and any suggestions are welcome. See ya!

Top comments (13)

Collapse
 
jbhrfx9280 profile image
jbhrfx9280

Creating The Sign Up Page Part I
Views.py
from .forms import RegisterForm

Giving me an import error. Tried all I know and cannot get past this. Please advise. Fyi: using django 4.1
Thank you
John

Collapse
 
earthcomfy profile image
Hana Belay

Hello there, have you created a forms.py file inside the users app and then the class RegisterForm?

Collapse
 
jbhrfx9280 profile image
jbhrfx9280

Yes created forms.py inside users app and RegisterForm. I have copied all your code. I have done a couple of django / app projects myself, no issues. Normally they are path related. Everything else works in your 10 part series so far but this. Some screenshots:
Image description
Image description

Thread Thread
 
earthcomfy profile image
Hana Belay

You have created forms.py inside users/templates/users directory. It should be in users/ that means where views.py, models.py and other files are located, so move it to the correct directory and let me know.

Thread Thread
 
jbhrfx9280 profile image
jbhrfx9280

I figured it out. My mistake, I had forms.py in the template/users folder. I know better than that. There was another minor error with finding home that I fixed. I'm in chapter 6 now "Django social apps auth". After installing social-auth-app-django (verified pip list) and updating settings.py, migrate etc, I'm now getting an error after code edit in user_management/urls.py. Error: "ImportError: cannot import name 'url' from django.conf.urls (c:..... Seems to not like "from django.conf.urls import url" in projects urls.py file. So need to figure out why. Any suggestions would be helpful. Thank you. John

Thread Thread
 
jbhrfx9280 profile image
jbhrfx9280

Ok so the issue is url has been removed from django 4. It's replaced by re_path. That's the fix.

Thread Thread
 
jbhrfx9280 profile image
jbhrfx9280

Things have also changed with Google. Before u can use oauth you must use a verified fqdn and must have url to terms of service and public policy url etc. Then several stages of verifications. So cannot just hit Google and get creds to do oauth. Maybe jeed to update yor thread with the things that have changed. My 2 cents. Still love your tutorial.

Thread Thread
 
earthcomfy profile image
Hana Belay

Yes, url has been removed in Django 4. I'll update the project and the articles soon.

Thread Thread
 
earthcomfy profile image
Hana Belay

In general, thanks for your feedback and I'm glad I could help :)

Collapse
 
loger231 profile image
rus • Edited

Hi, i have this
Help please

ImportError: cannot import name 'home' from 'users.views' (D:\reglog\user_management\users\views.py)

Image description

Collapse
 
aatmaj profile image
Aatmaj

Awesome post!

Collapse
 
earthcomfy profile image
Hana Belay

Thanks, am glad you enjoyed it

Collapse
 
ssadeghh profile image
ssadeghh

Hi
why we need to use initial in our code?