I am currently creating an register/login form with the Django framework, since I am new to this framework, I don't know much about the FORM API.
I am not using the FORM API, since I don't know if I can customize it. Is there any way to use my styling with the FORM API? As the state of now, I am just creating my own one, without using the API, but since the FORM API is more secure and much faster to set up for user creation, I would like to use it.
So my question is, can I implement custom styling with the FORM API? Including <input>
,<div>
etc..
Here is my HTML form:
{% if messages %}
<ul >
{% for message in messages %}
<li{% if message.tags %} {% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
<div >
<div style="background:black;">
<div >
<form method='POST' action="{% url 'users:register' %}" >
{% csrf_token %}
<span >
<i ></i>
</span>
<span >
Register
</span>
<div data-validate = "Enter username">
<input type="text" name="username" placeholder="Username" required>
<span data-placeholder=""></span>
</div>
<div data-validate="Enter password">
<input type="password" name="pass" placeholder="Password" required>
<span data-placeholder=""></span>
</div>
<div data-validate="Confirm password">
<input type="password" name="pass-confirm" placeholder="Confirm Password" required>
<span data-placeholder=""></span>
</div>
<div data-validate="Enter Email">
<input type="email" name="mail" placeholder="E-Mail" required>
<span data-placeholder=""></span>
</div>
<div >
<button type="submit" name="submit" value="submit">
Register
</button>
</div>
<div >
<a href="login">
Already registered?
</a>
</div>
</form>
</div>
</div>
</div>
Here is my views.py backend:
def register(request):
if request.method == "POST":
username = request.POST["username"]
password = request.POST["pass"]
password_confirm = request.POST["pass-confirm"]
email = request.POST["mail"]
submit = request.POST["submit"]
print("UserName : ", username)
print('Email : ', email)
print('Password : ', password)
print('Password Confirm : ', password_confirm)
SpecialSym =['$', '@', '#', '%', '?']
confirm = False
if request.POST.get("submit"):
if len(username) < 7:
print('Username must be more than 10 char.')
confirm = False
messages.error(request, "Username must be more than 10 char.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if len(username) > 15:
print('Username must be less than 15 char.')
confirm = False
messages.error(request, "Username must be less than 15 char.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if any(char in SpecialSym for char in username):
print('Username can\'t contain special characters.')
confirm = False
messages.error(request, "Username can't contain special characters", 'red')
return HttpResponseRedirect(reverse('users:register'))
if len(password) < 8:
print("Your password is too short")
confirm = False
messages.error(request, "Your password is too short.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if len(password) > 25:
print("Your password must be less than 25 char")
confirm = False
messages.error(request, "Your password must be less than 25 char.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if not any(char.isdigit() for char in password):
print('Password should have at least one numeral')
confirm = False
messages.error(request, "Your password should have at least one numeral ", 'red')
return HttpResponseRedirect(reverse('users:register'))
if not any(char.isupper() for char in password):
print('Password should have at least one uppercase letter')
confirm = False
messages.error(request, "Your password should have at least one uppercase letter ", 'red')
return HttpResponseRedirect(reverse('users:register'))
if not any(char.islower() for char in password):
print('Password should have at least one lowercase letter')
confirm = False
messages.error(request, "Your password should have at least one lowercase letter ", 'red')
return HttpResponseRedirect(reverse('users:register'))
if not any(char in SpecialSym for char in password):
print('Password should have at least one of the symbols $@#?')
confirm = False
messages.error(request, "Your password should have at least one of these symbols: $@#? ", 'red')
return HttpResponseRedirect(reverse('users:register'))
if (password != password_confirm):
print("Passwords don't match")
confirm = False
messages.error(request, "Passwords don't match.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if confirm == True:
messages.success(request, "Success! form submitted.", 'green')
return HttpResponseRedirect(reverse('users:register'))
return render(request, 'users/register.html')
CodePudding user response:
You can use in-built UserCreationForm
[django-doc], which is at the path from django.contrib.auth.forms import UserCreationForm
.
Now, as your current code, you don't need to use messages
framework, as the in-built Form
has already many validations, you have done.
In your code you can implement in following way, simply do this:
I am providing only a minimal reproducible example,as you have many css
classes in the templates so I only add my_class
to every field, you can add your own class, you can see it with Ctrl U
or page source
.
urls.py
from django.urls import path
from . import views
app_name = 'users'
urlpatterns = [
path('', views.register, name='home'),
path('success/', views.success, name='success')
]
views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password
from django.urls import reverse
from home.forms import MyUserCreationForm
def register(request):
if request.method == 'POST':
form = MyUserCreationForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password1 = form.cleaned_data['password1']
email = form.cleaned_data['email']
user_data = User(username=username,
password=make_password(password1), email=email)
user_data.save()
return HttpResponseRedirect(reverse('users:success'))
else:
form = MyUserCreationForm()
return render(request, 'users/register.html', {'form': form})
def success(request):
return render(request, 'users/thanks.html')
forms.py
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.contrib.auth import password_validation
from django.utils.translation import gettext, gettext_lazy as _
from django.contrib.auth.models import User
class MyUserCreationForm(UserCreationForm):
password1 = forms.CharField(
label=_("Password"),
strip=False,
widget=forms.PasswordInput(
attrs={'autocomplete': 'new-password', 'class': 'my_class', 'placeholder': 'password'}),
help_text=password_validation.password_validators_help_text_html(),
error_messages={'required': 'password is required'}
)
password2 = forms.CharField(
label=_("Password confirmation"),
widget=forms.PasswordInput(
attrs={'autocomplete': 'new-password', 'class': 'my_class', 'placeholder': 'confirm password'}),
strip=False,
help_text=_("Enter the same password as before, for verification."),
error_messages={'required': 'password confirm is required'}
)
email = forms.CharField(widget=forms.EmailInput(
attrs={'class': 'my_class', 'placeholder': 'Email'}), error_messages={'required': 'Email is required'})
class Meta:
model = User
fields = ['username', 'email']
error_messages = {
'username': {'required': 'Username is required'},
}
widgets = {
'username': forms.TextInput(attrs={'class': 'myclass', 'placeholder': 'Username'}),
}
Note:
you can use any class in any field, you can change here for every fieldattrs={'class': 'my_class')
, I have usedmy_class
in every field just for example, you can view it in page source.
Note
: The example might be a bit complex, since I have inherited and changed the django's inbuilt form for adding cssclasses
.
register.html or template file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.red{
color:red;
font-size:1.15rem;
}
</style>
</head>
<body>
{% if form %}
<form method="POST" novalidate>
{% csrf_token %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<div >
<p>{{error}}</p>
</div>
{% endfor %}
{% endif %}
{% for field in form %}
<div>
{{field.label_tag}} {{field}}
<br>
{% for error in field.errors %}
<div >
<span>{{error}}</span>
</div>
{% endfor %}
</div>
{% endfor %}
<input type="submit" value="Save">
</form>
{% else %}
<p>There is some error, form does not come from view.</p>
{% endif %}
</body>
</html>
thanks.html (which will be used for redirection after successfully submitting the form)
<body>
<h2>You are now a user! logged in !</h2>
</body>
Through this example, your data successfully saved in the database, you can see it by creating superuser, through python manage.py createsuperuser
and by logged in into the admin site, in the Users
table.
The above work can become more easy with class based authentication views
[django-doc].