GET and POST requests, CSRF token and forms in Django

- Andrés Cruz

En español

Let's create a function called add() , to add comments; for now, the section to draw a view:

def add(request):
    return render(request,'add.html')

We have to create a page:

comments/templates/add.html

<!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>
</head>
  <body>
    <h1>Page to add</h1>
  </body>
</html>

We can create routes in each application which we then register in the project; we are going to create a file called urls.py with the following content:

comments/urls.py

from django.urls import path
from . import views

app_name='comments'
urlpatterns = [
    path('add', views.add, name='add')
]

Now, let's create an HTML form to create a comment:

templates/comments/add.html

<form method="post">
    <label for="id_text">Text:</label>
    <textarea name="text" cols="40" rows="10" class="form-input" required id="id_text">
</textarea>
    <input type="submit" value="Enviar">
</form>

It will look like:

Formulario básico en Django
Formulario básico en Django

The form is really simple, we have a POST type form that points to the /comments/add route, which is the call view function add(), which is the same one that is responsible for painting this form.

When submitting the form we will see an error like the following:

Error 403
Error 403

CSRF protection

The previous error happens because, to avoid Cross-site request forgery or cross-site request forgery, Django uses a token that it generates and injects into the forms; so, to be able to use this token, just use the following directive:

<form method="post">
    {% csrf_token %}
    ***
    <input type="submit" value="Send">
</form>

And with this, the request would already pass.

Usually, when we want to change the data model of the project, in this case, create an element, we use a POST type request from the HTML forms:

  • GET requests are used to query data.
  • POST type requests are used to change the data model, meaning to create, update or delete.

Now, we have to receive this POST request from the view function; for that, we have to handle the user's request, which is the parameter that we receive by default in the view functions; for example:

def add(request):
    return render(request,'comments/add.html')

Through:

request.method

Which returns the type of request, GET or POST.

With this, we can obtain everything that has to do with the request that our user made from the web page through the form; such as the headers, request type and of course, the form data.

As the add() function we are going to use it to handle both types of requests:

  • Request of type GET, to paint the HTML page through the template.
  • POST type request, to process the form data.

So, to determine the process that we are going to execute according to a type of request, we have:

request.method == 'POST'

And the code is as follows:

def add(request):

    if request.method == 'POST':
        print("Estamos en el post")
        return 

    return render(request,'comments/add.html')
  • If the request is GET, we paint the form using the template.
  • If the request is of type POST, we print a message through the terminal.

If you submit the form, the browser should see an exception of type ValueError indicating that it is not a valid HTTP response; since, we are not returning anything; but, by the terminal, we will see the message of:

we are in the post

At the moment we manage to send data to our view function with which we are printing it by console; but, how can we create a record in the database; for that, we need to know the way in which we can get this data from the request.

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy