Django es de código abierto, esto permite a la comunidad generar librerías que apoyen la misión de Django. Una de estas librerías se llama rest_framework
, y es la que aprenderemos a usar, pues es muy importante conocerla.
La cosa desde aquí se pone oscura. Si has llegado hasta aquí, date una palmada en la espalda, ya que posees lo básico-intermedio de Django.
Ahora, vamos a pasar por el horroroso, insípido, tortuoso, complejo mundo de las APIs.
Necesitaremos una forma de probar nuestro api, puede ser:
Yo usare la extension de Visual Studio Code REST Client.
Estos conceptos son importantes tenerlos en cuenta:
serializer
: Un serializador permite convertir un modelo Django en un formato orientado a texto. En resumen, permite la conversión de un queryset (modelo) a un formato como JSON, XML, etc.queryset
: Es, en resumen, una consulta que se envía a un modelo. Siempre devuelve uno o más registros correspondientes al modelo seleccionado.validators
: Este es más perteneciente a un modelo de Django, se refiere a las validaciones para que una entrada corresponda al formato de un modelo dado. (El tipo de dato, la longitud máxima, formato como email o numérico, etc.)APIView
: No es nada más que una vista que controla una API respecto a un modelo. Por ejemplo, podemos crear una vista que solo sirva para listar (obtener) y crear nuevos registros dentro de nuestra base de datos respecto a un modelo.Class based views
: Hemos usado vistas funcionales (function based views
), pero ahora toca usar vistas basadas en clases Python. Que tienen un comportamiento similar, pero más enfocado a objetos. Lo cual viene de la perra, pues literal, nuestros modelos son clases Python que Django relaciona con registros.stateless
: Dependiendo de una petición, la API devuelve un JSON o XML, etc., según corresponda. En los navegadores web, suele responder con un panel visual.El sitio oficial del proyecto está en https://www.django-rest-framework.org/
Recuerda tener un entorno virtual de Python creado y cargado!
Como toda librería de Python, rest_framework
debes instalarla desde pip
:
pip install djangorestframework
Documentacion de instalacion disponible en https://www.django-rest-framework.org/#installation
Una vez instalado, debemos dirigirnos a nuestro archivo settings.py
dentro de la carpeta del proyecto (ProyectoDjango/
):
1 2 3 4 5 |
|
Y ya está, la instalación ha terminado, ahora vamos a usarla.
Montaremos nuestra API en una nueva aplicación, para ello simplemente usamos el comando:
py manage.py startapp api
En mi caso la llamare API, muy clarificador.
Como es de costumbre, tenemos que registrar la app en el archivo settings.py
de nuestro proyecto.
Un serializador permite transformar un queryset en un formato estructurado plano, como JSON, XML, etc...
Estos se definen en un archivo por separado que por convención es llamado serializers.py
dentro de la aplicación api
o también lo podemos crear en la aplicación tienda
que es donde está el modelo.
En mi caso, lo creare dentro de api
:
1 2 3 4 5 6 7 8 9 10 11 |
|
Como puedes ver, es muy simple el serializador.
Una Class Based View 🍷 es una vista basada en clases, que se comporta casi idéntico a una funcional, en REST framework debemos usar clases.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
En nuestro archivo urls.py
que debemos crear dentro de api
, declaramos la ruta y su vista:
1 2 3 4 5 6 7 8 9 10 11 |
|
Luego incluimos este urls.py
dentro de urls.py
de nuestro proyecto:
1 2 3 4 |
|
Ojalá tener una sesión iniciada, así podemos ver todas las rutas definidas. Simplemente vamos a Iniciar Sesión.
Ahora, si nos dirigimos a http://127.0.0.1:8000/api/productos/ deberíamos ver algo así:
Nótese que esta lista todos los productos, tal cual le hemos dicho.
Esta vista solo cumple esa función de listar.
Y si vamos a http://127.0.0.1:8000/api/productos/crear/:
En esta vista podemos observar que hay un formulario más abajo, que permite rellenar los campos, esto es así ya que heredamos la vista de generics.CreateAPIView
, que permite crear productos.
En resumen, esto es muy simple. Definimos vistas y indicamos como deben comportarse.
Pero, las APIs no las usa un usuario a través de un navegador, estas son usadas por aplicaciones que las implementan. Estas pueden ser el Front-End del sitio u otra aplicación de terceros que simplemente las usan.
Ahora haremos una pequeña prueba con la extensión de VSC para probarla, tenemos que crear un archivo .http
donde queramos.
Yo la creare dentro de la app api
llamándola API-TESTER.http
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Aparecerá un botón Send request
, si le damos se ejecutará la consulta y nos mostrará la respuesta en una ventana dividida.
En el caso del POST, le hemos dicho a nuestra vista que solo peticiones provenientes de sesiones con un usuario con permiso de administrador serán aceptadas, por lo que si lo ejecutamos tal cual nos lanzara un error mencionando que no se encontraron las credenciales.
1 2 3 |
|
Esto lo podemos solucionar agregando el header
llamado Authorization
, que es como las APIs suelen autentificar a un usuario, por lo que, en nuestro archivo .http el método POST quedaría:
1 2 3 4 5 6 7 8 9 10 |
|
Y así podremos ejecutar la petición, la cual debería crear el producto "Soldadura de madera" y guardarlo en la base de datos.
Nótese que el campo
slug
ha sido rellenado automáticamente, igualmente con el campocreacion
. Esto no es por la API, es como está construido el modelo.
Elslug
por otra parte debemos especificarle a la API que no es editable. Ya que nuestro modelo lo crea por nosotros automáticamente.
También cabe mencionar que nuestra respuesta fue un JSON, y en nuestro navegador web fue un panel. Esto se debe al stateless. Responde como debe según el contexto de la petición.
Ahora bien, quedan hacer la forma de actualizar y eliminar un registro, esto se realiza con el método PUT para editar y DELETE para eliminar.
Entonces, dentro de views.py
de nuestra aplicación api
ponemos:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Y luego registramos las rutas en api/urls.py
:
1 2 3 4 5 6 7 8 |
|
Y ya está, ahora probamos con la extensión:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Obviamente, debemos especificar el header
Authorization
para poder ejecutarlas.
Nótese que cada una de las peticiones devuelven distintos códigos HTTP:
- HTTP/1.1 200 OK: Para la petición LISTAR y ACTUALIZAR
- HTTP/1.1 201 Created: Para la petición CREAR
- HTTP/1.1 204 No Content: Para la petición ELIMINAR
Estos códigos son importantes a la hora de desarrollar un cliente que use nuestra API.
Estos códigos son llamados HTTP Response Status Codes y te recomendamos echarles un vistazo.
Para realizar las operaciones que están bajo IsAuthenticated
, IsAdminUser
, u otro permiso que requiera una sesión activa. Es necesario pasar un header que le permita a Django saber quiénes somos.
Para ello, en la petición HTTP, debajo debemos poner el header Authorization
e indicar nuestras credenciales en nuestro API-TESTER.http
tal que:
1 2 3 4 5 |
|
El header
Authorization
esta estandarizado.
El formato esusername:password
dentro deAuthorization
.
Lo mismo para los otros métodos.
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 |
|
El obvio problema aquí es que el usuario y su contraseña están en texto plano, para evitar esto es que existe el sistema de autenticación JWT (que es solo un pez más dentro de la gran pecera)
Dejaremos lo del JWT y demás para el próximo capitulo, ya que como dije, la cosa se pone oscura.