Working with forms in Django, creating a record
In HTML, a form is a collection of elements within <form>...</form> that allow a user to enter text, select options, among other operations; etc., and then return that information. to the server, in this case, to Django.
Some of these form interface elements (text input or check boxes) are embedded in the HTML itself. Others are much more complex; an interface that displays a date picker or allows you to move a slider or manipulate controls will generally use JavaScript and CSS, as well as HTML <input> form elements to achieve these effects.
Let's create the process to use the form to create records using the Form in Django that we defined earlier; For that we are going to use a creation function that we are going to use both to display the form and to create the records.
def create(request):
form = ProductForm()
return render(request, 'create.html', { 'form' : form })
As you can see, we instantiate our form class and then pass this instance to a template that has the following definition:
<form method="post">
{% csrf_token %}
{{ form }}
<button type="submit">Enviar</button>
</form>
As you can see, we print the form that we encapsulate within an HTML form and define it as Post type, since POST type requests are the ones we generally use to create or update records.
Get and post type forms
Now, we want to use this form to create our records, for that we must detect when we paint the form (get) or when we process the data (post), for that we detect the type of method, if it is Post type (request.method == "POST"), in this case, in addition to asking if the form is valid (if the validations performed were passed), then we generate an instance of product, which is a model, and we establish its data:
product = Product()
product.title = form.cleaned_data['title']
product.price = form.cleaned_data['price']
product.description = form.cleaned_data['description']
product.category = form.cleaned_data['category']
And then we save:
product.save()
cleaned_data allows us to work with the cleaned data.
Full application code
def create(request):
form = ProductForm()
if request.method == "POST":
#print(request.POST['title'])
form = ProductForm(request.POST)
if form.is_valid():
print("Valido")
#form.save()
product = Product()
product.title = form.cleaned_data['title']
product.price = form.cleaned_data['price']
product.description = form.cleaned_data['description']
product.category = form.cleaned_data['category']
product.save()
else:
print("Invalido")
return render(request, 'create.html', { 'form' : form })
<form method="post">
{% csrf_token %}
{{ form }}
<button type="submit">Enviar</button>
</form>
Conclusions
As you can see, using the form that we created in the previous entry is easy to do this type of operation. In the creation function, it has only two steps: painting the form and obtaining the data to register it in the model and then save it.
The models for the forms are classes that define the structure based on a Python class with its corresponding attributes; these classes allow:
- Define the structure of the form.
- Apply server-side and client-side validations.
- Being able to reuse forms easily.
Case study
To use the forms, we can define them in a separate file at the application level; which by convention is called how forms.py.
With this in mind, let's create the following class:
comments/forms.py
from django.forms import ModelForm, Textarea
from .models import Comment
class CommentForm(ModelForm):
class Meta:
model = Comment
fields = ('text',)
Explanation of the above code
ModelForm type forms offer us a simple scheme to define form fields; as you can see, it's a Python class that inherits from the aforementioned class.
Then, we have to define within this form class, a class called Meta, to define the structure of the forms; that is, to which models is this form related, and what are the fields; fields is nothing more than a python tuple.
These classes are very customizable and you can define saving processes, initialization at the class level, define attributes, customize form fields, validations, among others; although at the moment, we have a minimal example.
For model classes, it has been usual to create an instance and in this case, pass to the template.
Let's go to the add() function, and pass it as the second parameter, the form:
from .forms import CommentForm
// ***
form = CommentForm()
return render(request,'comments/add.html',{'form':form})
From our template, we can print the complete form:
{{ form }}
And with this, all the fields that you have defined appear along with the LABEL:
Or by fields, independently:
{{ form.text }}
Use the one that seems best to you and suits you.
Process forms
From the request, we can obtain the data of the form that we are sending via POST or GET as we saw before; so, to establish the data that goes via POST in the previous form:
form = Form(request.POST)
We pass it as initialization to the form.
Case study
The add() function will look like this:
def add(request):
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save()
else:
form = CommentForm()
return render(request,'comments/add.html',{'form':form})
As you can see in the code above, from the same model, we can use the save() function to create a comment.
With this, you can perform some tests and send data from the template form:
And you will see in your database:
If you put invalid data, that is, a form without values, you will see a client-side validation jump:
- Andrés Cruz
Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter