To receive data from the user and submit it to the server, we will use forms
index.html
<!-- To submit data, method should be post --> <!-- action specifies the url to which the data is submitted. If nothing is specified, data is sent to the view function linked with index.html --> <form method="post" action=""> <input type="text" name="username" placeholder="Username"> <input type="password" name="password" placeholder="Password"> <input type="submit" name="submit" value="Login"> </form>urls.py
path("",views.index,name='index'), #form will be sent to view.indexviews.index
def index(request):
if request.method == 'POST':
#Get the fields
username = request.POST.get('username')
password = request.POST.get('password')
Django forms can be used which comes with several conveniences like validators, interaction with database etc
1) Create a form class in app3/forms.py (same as that of model)
from django import forms
class FormName(forms.Form):
name = forms.CharField()
email = forms.EmailField()
text = forms.CharField(widget=forms.Textarea)
#Pass on the widget textarea. Otherwise, input looks same as that of name and email
2) Use the form class in views.py
from app3 import forms
def form_name_view(request):
form = forms.FormName()
return render(request,'form_page.html',context={'form':form})
3) Inject the form into form_page.html. Note that csrf_token is necessary for posting the form.
<body>
<h1>Form Page</h1>
<form method="post">
<!-- {form.as_p} renders the fields in separate lines -->
{% csrf_token %}
<!-- This is a security token, without which the form breaks -->
</form>
</body>
Changes in form input attributes can be done through views.py (demonstrated later). It can also be done in the template by creating custom template tags
We can access the submited data by grabbing the form with request object in views.py
def form_name_view(request): # Linked with urls.py to get the request object
if request.method == 'POST':
form = forms.FormName(request.POST)
do_something_with_data(form)
form = forms.FormName()
return render(request,'form_page.html',context={'form':form})
def do_something_with_data(form):
if form.is_valid(): #Check if form fields are valid
# Do Something
print("Validation success")
# Access the data
name = form.cleaned_data['name']
print("NAME :", name)
This is done by creating methods clean_{fieldName} in the form class
class FormName(forms.Form):
name = forms.CharField()
email = forms.EmailField()
text = forms.CharField(widget=forms.Textarea)
#Each field has certain default validation check.
#We can also add custom Validation
#Eg. Lets demonstrate botcather
botcatcher = forms.CharField(required=False,widget=forms.HiddenInput)
##Hidden input widget hides the field from rendering.
## But the field will be present in HTML element which a bot uses
#Define a method starting with clean_<field_name>.
#Django will automatically look for this method while Validation
def clean_botcatcher(self):
botcather = self.cleaned_data['botcatcher']
if len(botcather):
raise forms.ValidationError("Gotcha Bot!")
return botcather
Django's built-in validators can also be used. Look the documentation for complete list of validators
from django.core import validators
##Using django built-in validators
botcather1 = forms.CharField(required=False,
widget=forms.HiddenInput,
validators=[validators.MaxLengthValidator(0)])
Custom validators can also be passed in through validators argument
#Custom validator can also be passed in through validators arg
#needs first argument to be 'value'
def check_for_z(value):
if value[0].lower() != 'z':
raise forms.ValidationError("Needs to start with Z")
refree = forms.CharField(validators=[check_for_z])
Note: Can also be used with model fields
We can also have validators for all fields defined under a single method
# Changing label
verify_email = forms.EmailField(label="Re-enter email")
##We can also have a single validator for all fields at once
def clean(self):
#grab all clean data
all_clean = super().clean()
##Prints only clean data
print(super().clean())
if 'email' in all_clean and 'verify_email' in all_clean:
if all_clean['email'] != all_clean['verify_email']:
raise forms.ValidationError("Make sure emails are same")
Create model and migrate
In forms.py
Instead of inherting from forms.Forms, we will use forms.ModelForm in forms.py
We then add an inline class called meta which connects the model to form
In views.py
Grab the form and use form.save() to save the form into database
models.py
from django.db import models
# Create your models here.
class SignUp(models.Model):
name = models.CharField(max_length=264);
email = models.EmailField();
NOTE: Remember to migrate and register model in admin.py
forms.py
Changes to input attributes are demonstrated
from django import forms
from app3.models import SignUp
class Form_SignUp(forms.ModelForm):
#Can have validators/other modifications here. Not Compulsory.
name = forms.CharField(label="",widget=forms.TextInput(attrs={'placeholder':'Name'}))
#field names and form names should match
class Meta:
model = SignUp #Assign model
fields = "__all__" # All fields in model
#exclude = [exclude1,exclude2] #All model fields except
#fields = (include1,include2) #Only these model fields
views.py
def form_signUp_view(request):
form = forms.Form_SignUp()
if request.method == 'POST':
form = forms.Form_SignUp(request.POST)
if form.is_valid():
form.save(commit=True) # Save form to database
else:
print("Invalid")
return render(request,'form_page2.html',context={'form':form})