I developed a login and registration system using Django on a single HTML page with a tabbing system. But, I encountered an error: upon registering, the page just refreshes. To troubleshoot, I debugged by printing errors to the console. It printed that the form is invalid. I intentionally provided invalid details to troubleshoot, like entering a password similar to the username or a password that isn't longer than 8 characters. It printed that in the console, but I want it to show the errors in the HTML template for each field. So, I wrote a login-register view. Everything seems to be okay in the view, but it still isn't showing the errors in the HTML template.
Forms
class CustomUserCreationForm(UserCreationForm):
email = forms.EmailField(label="Email", max_length=255, required=True)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field_name in self.fields:
field = self.fields[field_name]
field.widget.attrs.update({'class': 'u-full-width bg-light pb-2', 'placeholder': field.label})
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
Views
def login_register_view(request):
if request.user.is_authenticated:
return redirect('core:home')
if request.method == 'POST':
action = request.POST.get('action')
if action == 'login':
# login functionality
elif action == 'register':
registration_form = CustomUserCreationForm(request.POST)
if registration_form.is_valid():
user = User.objects.create_user(
username=registration_form.cleaned_data['username'],
email=registration_form.cleaned_data['email'],
password=registration_form.cleaned_data['password1']
)
user.save()
return redirect('core:login_register')
login_form = CustomAuthenticationForm()
registration_form = CustomUserCreationForm()
context = {
'login_form': login_form,
'registration_form': registration_form,
}
return render(request, 'accounts/login_register.html', context)
HTML Template
<form method="post">
{% csrf_token %}
<div class="form-group">
{{ registration_form.username.label_tag }}
{{ registration_form.username }}
{% if registration_form.username.errors %}
<span class="error">{{ registration_form.username.errors }}</span>
{% endif %}
</div>
<div class="form-group">
{{ registration_form.email.label_tag }}
{{ registration_form.email }}
{% if registration_form.email.errors %}
<span class="error">{{ registration_form.email.errors }}</span>
{% endif %}
</div>
<div class="form-group">
{{ registration_form.password1.label_tag }}
{{ registration_form.password1 }}
{% if registration_form.password1.errors %}
<span class="error">{{ registration_form.password1.errors }}</span>
{% endif %}
</div>
<div class="form-group">
{{ registration_form.password2.label_tag }}
{{ registration_form.password2 }}
{% if registration_form.password2.errors %}
<span class="error">{{ registration_form.password2.errors }}</span>
{% endif %}
</div>
<button type="submit" name="action" value="register" class="btn btn-dark btn-full btn-medium">Register</button>
</form>
The problem is, that you reinitialize the form with registration_form = CustomUserCreationForm()
in case it is not valid. Thus, removing also it's errors.
Return the form with its POST
data. E.g. something like this:
...
elif action == 'register':
registration_form = CustomUserCreationForm(request.POST)
if registration_form.is_valid():
user = User.objects.create_user(
username=registration_form.cleaned_data['username'],
email=registration_form.cleaned_data['email'],
password=registration_form.cleaned_data['password1']
)
user.save()
return redirect('core:login_register')
else:
context = {
'registration_form': registration_form,
}
return render(request, 'accounts/login_register.html', context)
...