-
Notifications
You must be signed in to change notification settings - Fork 10
User Registration
Django version: 1.10.5
Add the URL in urlpatterns
in app/urls.py
:
urlpatterns = [
url(r'^register/$', app_views.register, name='register'),
]
Create a file forms.py
in app
and import forms
from Django.
from django import forms
We are going to use the form UserCreationForm
provided by Django as our form1
, the form contains basic information we must know about our users. The form also needs a model called "User":
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
We could simply use UserCreationForm
and we don't need to write the forms.py
file. But it only comes with username and password and we do want to know more about our users. Therefore, we are going to extend the UserCreationForm
by creating a form of our own:
class RegistrationForm(UserCreationForm):
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
email = forms.EmailField(max_length=254)
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2')
Here we use the User model from Django, it comes with several fields containing what we defined above(name and email) but not required by default. Since we want to know the name and email of our users, in our RegistrationForm
, we specify the 2 CharField and an EmailField as required(explained in the tips below). Once we are done with defining those fields, we need to add them into Meta
so the forms know which ones and in what order(from left to right) we want to put them in. (If we use a {% for %}
loop to display them through Django template, the website will show them in order.)
Tips:
In the form that we created, if we do not specify required=False
such as
email = forms.EmailField(max_length=254, required=False)
when we define a field, it will be a required information by default, and it will produce an error if users do not enter in an acceptable format(such as "12345" in EmailField
).
If we want to put some help text next to it, we can do
email = forms.EmailField(max_length=254, help_text='Blah blah blah.')
and then add the following in the template:
{% if field.help_text %}
{{ field.help_text }}
{% endif %}
Good! We are done with the required field, now we will use a different approach to recording optional information. Go to app/models.py and create our own model, `RegisterUser' for optional information:
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class RegisterUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
department = models.CharField(verbose_name='Department(Optional)', max_length=100, blank=True, null=True)
organization = models.CharField(verbose_name='Organization(Optional)', max_length=100, blank=True, null=True)
title = models.CharField(verbose_name='Title(Optional)', max_length=100, blank=True, null=True)
country = models.CharField(verbose_name='Country(Optional)', max_length=50, blank=True, null=True)
about= models.TextField(verbose_name='About(Optional)', max_length=500, blank=True, null=True)
You may notice that we have 2 more parameters here: blank and null. They tell the database to accept empty or blank value. If you want more information, please click on the link to read Django Documentation.
We also used a OneToOneField to relate the User object to this model. If we want to use any information in this RegisterUser
model, for instance, the department, we will call: .registeruser.department
(all lowercase).
Now we go back to app/forms.py
to add our second form.
from .models import RegisterUser
class AdditionalForm(forms.ModelForm):
class Meta:
model = RegisterUser
exclude = ('user')
Because we will use exactly the RegisterUser model we just created, so we don't need to define any other fields. However, we do want to exclude the 'user' object that relates the RegisterUser
model to the user, but we don't want to create a new user object with the same information in the database. Recall that this model is to store optional information, and all the crucial information is in our first form RegistrationForm
.
Now, we are going to create a view for or user registration. Go to app/views.py
and add the following:
def register(request):
if request.method == 'POST':
form1 = RegistrationForm(request.POST)
form2 = AdditionalForm(request.POST)
if form1.is_valid() and form2.is_valid():
model1 = form1.save()
model2 = form2.save(commit=False)
model2.user = model1
model2.save()
return redirect('index')
else:
form1 = RegistrationForm()
form2 = AdditionalForm()
return render(request, 'app/register.html', {'form1': form1, 'form2': form2})
The reason we have commit=False
in model2 = form2.save(commit=False)
is that we do not want form2
to create a new user, so when we create form2
, it does not sync to the database, it allows us to make changes before we sync them. After we assign the form1.user
to form2.user
, we call model2.save()
and the data of form1
and form2
goes under the same user in the database. After registration, we will redirect the user to our home page(redirect('index')
).
We just use 2 {% for %}
loops to display the required information and optional information as 2 columns:
{% for field in form1 %} <!-- or for field in form2 -->
<p>
{{ field.label_tag }}<br>
{{ field }}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
Last Documentation: User Login and Logout