36. Account creation
Next, we will implement the user account creation system.
Within the create_account.html
file, we will configure the account creation form to submit its data to the create_account
URL endpoint.
<form method="POST" action="{% url 'create_account' %}">
Django already validates the email using the email
tag in the HTML form, but for additional security and reliability, we will also validate the email within the create_account
view function.
Inside the views.py
file, we will import the validate_email
function and the ValidationError
exception, as the error message returned by the function is not a default Python exception.
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
To verify the passwords obtained via the forms, we will create a utility function called secure_password
inside the utility.py
file. This function will analyze the password passed as a parameter and return True
if it meets all the previously mentioned criteria.
from .utility import filter_product, min_max_price, order_products, secure_password
To enhance user security, we will enforce the following password criteria:
Must be between 8 to 20 characters.
Must contain at least:
One uppercase letter.
One lowercase letter.
One special character.
def secure_password(password: str) :
if len(password) < 8 or len(password) > 20:
return False
special_characters = set('" "!@#$%^&*()-+?_=,<>/""''|.;:')
has_lower = has_upper = has_number = has_special = False
for character in password:
if character.islower():
has_lower = True
elif character.isupper():
has_upper = True
elif character.isdigit():
has_number = True
elif character in special_characters:
has_special = True
if has_lower and has_upper and has_number and has_special:
return True
return False
Next, we will edit the create_account
view function to implement the account creation functionality:
def create_account(request):
error = None
if request.user.is_authenticated:
return render(request, 'user/create_account.html')
if request.method == "POST":
data = request.POST.dict()
email = data.get("email", "").strip() # Ensure email is stripped of whitespace
password = data.get("password")
confirm_password = data.get("confirm_password")
if email and password and confirm_password: # Check if all fields are filled
try:
validate_email(email) # Validate email format
except ValidationError:
error = "invalid_email"
else:
if secure_password(password) :
if password == confirm_password:
user, created = User.objects.get_or_create(username=email, email=email)
if not created:
error = "user_exists"
else:
user.set_password(password)
user.save() # Save the user
# Authenticate and log in the user
user = authenticate(request, username=email, password=password)
if user is not None:
login(request, user)
# Handle client creation or update
id_session = request.COOKIES.get("id_session")
if id_session:
client, created = Client.objects.get_or_create(id_session=id_session)
else:
client, created = Client.objects.get_or_create(email=email)
client.user = user
client.email = email
client.save()
return redirect('store')
else:
error = "different_password"
else :
error = "weak_password"
else:
error = "fill"
context = {"error": error}
return render(request, 'user/create_account.html', context)
The code above can be described below:
Function Name:
create_account
Parameters:
request
(HTTP request object)Local Variable:
error
initialized toNone
Authentication Check
Check: If user is authenticated
Action: Render the 'create_account.html' template
HTTP POST Method Handling
Check: If request method is "POST"
Action: Convert
request.POST
data to dictionary (data
)
Form Data Validation
Check: Presence of 'email', 'password', and 'confirm_password' in
data
Action: Extract 'email', 'password', and 'confirm_password' from
data
Email Validation
Try: Validate email format using
validate_email
Exception: Set
error
to "invalid_email" ifValidationError
occurs
Password Confirmation
Check: If 'password' matches 'confirm_password'
Action: Attempt to create or get a
User
with given 'email'
User Existence Check
Check: If user already exists
Action: Set
error
to "user_exists" if user already exists
New User Creation
Action: Set user's password and save the user object
User Authentication and Login
Action: Authenticate user with provided 'email' and 'password'
Action: Log in the authenticated user
Session Handling for Anonymous Users
Check: If "id_session" exists in cookies
Action: Get or create
Client
with 'id_session'Else: Get or create
Client
with 'email'
Client Association
Action: Associate
Client
with the authenticated userAction: Save
Client
object
Redirect and Error Handling
Redirect: Redirect to 'store' on successful account creation
Else: Set
error
to "different_password" if passwords do not matchElse: Set
error
to "fill" if required fields are missing
Context and Template Rendering
Context: Pass
error
to context dictionaryRender: Render 'create_account.html' with context
Note: The Client
model is used to store all the user's information. This model is linked to the User
model in a one-to-one relationship.
The account creation system is now fully operational, as demonstrated in the images below:


Client
instance is successfully created, indicating that the account creation system is functioning as expected.Note: The cart content of anonymous users is preserved and associated with their account upon account creation throught their Id session
.

Last updated