I wanted to create my own registration form without using the crispy forms, I wanted to give my own styling to the form, please help me with steps or provide me a tutorial link.
Thank You
CodePudding user response:
Creating the HTML form
Create a HTML form in your Django template, with method
as POST
. Example form:
<form action="/register/">
<label for="username">Username</label><br>
<input type="text" id="username" name="username"><br>
<label for="password">Email</label><br>
<input type="email" id="email" name="email"><br><br>
<label for="password">Password</label><br>
<input type="password" id="password" name="password"><br><br>
<input type="submit" value="Submit">
</form>
Add any sort of styling you'd want to.
Creating the form using Django Forms
Now, you could always request.POST.get("username")
, request.POST.get("password")
, and request.POST.get("email")
, but this is crude and may not be secure. Django forms will help you use all of Django's built-in security measures.
In your forms.py
,
from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = User
fields = ('username','password','email')
The first line imports the User model from Django. In the next lines, this code creates the form, and finally, the fields are specified, which are username
, password
, email
.
Creating the view for the form
Now, in your register view, you can, firstly, import the form you created in forms.py
, and then
from app.forms import UserForm
def register(request):
if request.method == "POST":
user_form = UserForm(data=request.POST)
if user_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
else:
print(user_form.errors)
return redirect("/login/")
else:
user_form = UserForm()
return render(request, "app/registration.html", {"user_form": user_form})
In the above code, I'm importing the form. Then, I'm checking if the method is POST
, because if it isn't, then it means the form hasn't been submitted yet, and just appeared at the page for the first time. Then I'm passing the data entered to the form. If the form is valid, I'm sending the form to the model. But you can't just enter a password as plaintext into the model. You need to encode it. set_password
encodes, hashes, and salts the password so that even if someone manages to hack in to your website, they won't be able to access anyone's accounts because the passwords are stored as random strings, and even if they typed the random string in the login form, it wouldn't work, see Computerphile videos on hashing algorithms and security to know more. Then I'm saving the record to the user model and the user's been registered. I redirect to login and this if condition is finished. Then we need to handle what will happen if the request method is get and the user appeared at the register page for the first time. I'm passing the user form over to the template here.
Custom Validation in Django Forms
This is one of those reasons why Django Forms is the way to go. You can use all of Django's built in features. If you had to do this on your own, you'd just be reinventing the wheel, and that's a waste of time.
In your form (in forms.py
), add a method clean_username
to the UserForm class. Note that the suffix of clean
in the function name must be the variable or the field that you wish to validate.
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = User
fields = ('username','password','email')
def clean_username(self):
data = self.cleaned_data.get('username')
if "@" in data:
raise forms.ValidationError("Contains @")
return data
Because clean_username
is a method of the UserForm
class, it takes in self as an argument. Below, I define a variable called data
. data
is set to self.cleaned_data.get('username')
. Here, self.cleaned_data
returns a dictionary of the data submitted to the form which has been validated by the form. cleaned_data
contains the data of only those fields that have passed Django's built in validation tests. From that dictionary, I'm selecting the username
field.
Now I'm checking for @
in the username
. If @
exists in the username, I raise a ValidationError
"Contains @". You can change this error name to whatever you would like. Then I'm returning the data to let it pass from the clean_username
check only if it passed the validation tests.
Hope this helped, thank you.
CodePudding user response:
You can use tweak widget I think that can help you to create your own reg form