Thursday, October 17, 2019

A view to allow visitors to create a user account

In the application we developed till now, the existing users can now log in, log out, change their password, and reset their password. Now, we will need to build a view to allow visitors to create a user account.

Now we'll create a simple view to allow user registration on our website. Initially, we have to create a form to let the user enter a username, their real name, and a password. Edit the forms.py file located inside the account application directory and add the following code to it:

from django.contrib.auth.models import User
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(label='Password',
widget=forms.PasswordInput)
password2 = forms.CharField(label='Repeat password',
widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username', 'first_name', 'email')
def clean_password2(self):
cd = self.cleaned_data
if cd['password'] != cd['password2']:
raise forms.ValidationError('Passwords don\'t match.')
return cd['password2']


We have created a model form for the user model. In our form, we include only the username, first_name, and email fields of the model. These fields will be validated based on their corresponding model fields.

For example, if the user chooses a username that already exists, they will get a validation error because username is a field defined with unique=True. We have added two additional fields—password and password2 —for users to set their password and confirm it. We have defined a
clean_password2() method to check the second password against the first one and not let the form validate if the passwords don't match.

This check is done when we validate the form calling its is_valid() method. You can provide a clean_<fieldname>() method to any of your form fields in order to clean the value or raise form validation errors for a specific field. Forms also include a general clean() method to validate the entire form, which is useful to validate fields that depend on each other.

Django also provides a UserCreationForm form that you can use, which resides in django.contrib.auth.forms and is very similar to the one we have created.

Edit the views.py file of the account application and add the following code to it:

from .forms import LoginForm, UserRegistrationForm
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
# Create a new user object but avoid saving it yet
new_user = user_form.save(commit=False)
# Set the chosen password
new_user.set_password(
user_form.cleaned_data['password'])
# Save the User object
new_user.save()
return render(request,
'account/register_done.html',
{'new_user': new_user})
else:
user_form = UserRegistrationForm()
return render(request,
'account/register.html',
{'user_form': user_form}) 


The view for creating user accounts is quite simple. Instead of saving the raw password entered by the user, we use the set_password() method of the user model that handles encryption to save for safety reasons.

Now, edit the urls.py file of your account application and add the following URL pattern:

path('register/', views.register, name='register'),

Finally, create a new template in the account/ template directory, name it register.html, and make it look as follows:

{% extends "base.html" %}
{% block title %}Create an account{% endblock %}
{% block content %}
<h1>Create an account</h1>
<p>Please, sign up using the following form:</p>
<form action="." method="post">
{{ user_form.as_p }}
{% csrf_token %}
<p><input type="submit" value="Create my account"></p>
</form>
{% endblock %}


Add a template file in the same directory and name it register_done.html. Add the following code to it:

{% extends "base.html" %}
{% block title %}Welcome{% endblock %}
{% block content %}
<h1>Welcome {{ new_user.first_name }}!</h1>
<p>Your account has been successfully created. Now you can <a href="{% url
"login" %}">log in</a>.</p>
{% endblock %}

Now, open http://127.0.0.1:8000/account/register/ in your browser. You should see the registration page you have created like below:





Fill in the details for a new user and click on the CREATE MY ACCOUNT button. If all fields are valid, the user will be created, and you will get the following success message:


Click on the log in link and enter your username and password to verify that you can access your account. Now, you can also add a link to registration in your login template. Edit the registration/login.html template; take a look at the following line:

<p>Please, use the following form to log-in:</p>

Replace it with the following:

<p>Please, use the following form to log-in. If you don't have an account <a
href="{% url "register" %}">register here</a></p>

Thus we made the signup page accessible from the login page.

Here I am ending this post. In the next post we'll extend the user model to include additional data.
Share:

0 comments:

Post a Comment