Django REST Framework nos permite trabajar con vistas regulares de Django. Facilita el procesamiento de requests HTTP y proporciona respuestas HTTP adecuadas. En esta sección, comprenderá cómo implementar las vistas de Django para el servicio web Restful. También hacemos uso del decorador @api_view.
Antes de trabajar en los serializadores Django REST Framework, debe asegurarse de que ya instaló Django y Django REST Framework en su entorno virtual. Puedes consultar los siguientes tutoriales:
A continuación, puede crear un proyecto llamado emt y una aplicación llamada transformers. Consulte los siguientes artículos para comprobar cómo crear un proyecto y una aplicación en Django.
En esta sección, utilizaremos PostgreSQL. Tienes que crear una base de datos llamada emt en PostgreSQL. Puede consultar el siguiente enlace para la instalación.
Instalar PostgreSQL en Windows
Nota: si necesita trabajar con SQLite, puede continuar usando la base de datos predeterminada.
Para hacer uso de PostgreSQL, necesitamos instalar un adaptador de base de datos Python-PostgreSQL (psycopg2). Este paquete ayuda a Django a interactuar con una base de datos PostgreSQL. Puede usar el siguiente comando para instalar el paquete psycopg2. Asegúrese de que la carpeta bin de PostgreSQL esté incluida en las variables ambientales PATH y que el entorno virtual esté activado antes de ejecutar el comando.
pip instalar psycopg2
Ahora, necesita configurar la base de datos PostgreSQL en su proyecto Django. De forma predeterminada, la configuración de la base de datos tiene un motor de base de datos SQLite y un nombre de archivo de base de datos. Puede verificar el archivo de Python setting.py y reemplazar la configuración de la base de datos predeterminada con la configuración de la base de datos PostgreSQL.
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'emt', 'USER': 'username', 'PASSWORD': 'password', 'HOST': '127.0.0.1', 'PORT': '5432', } }
Aquí, el nombre se refiere al nombre de la base de datos, el usuario y la contraseña se refieren al nombre de usuario y la contraseña de Postgres.
Por último, necesitamos instalar el paquete httpie en nuestro entorno virtual. Estaremos componiendo comandos HTTPie para la operación CRUD. Puede activar el entorno virtual y ejecutar el siguiente comando
instalación de pip –actualización de httpie
Ahora, creemos el modelo y el serializador.
Creación de modelo y serializador
Antes de entrar en las vistas basadas en clases, creemos un modelo y su serializador, lo que ayuda a demostrar el funcionamiento de las vistas basadas en funciones.
Crear modelo
En Django, los modelos son clases que tratan con bases de datos de forma orientada a objetos. Cada clase de modelo hace referencia a una tabla de base de datos y cada atributo de la clase de modelo hace referencia a una columna de base de datos. Aquí, crearemos un modelo de Transformador simple en Django, que almacena el nombre del personaje del transformador, el modo alternativo, la descripción y si el personaje está vivo o muerto. Requerimos los siguientes atributos para nuestra entidad Transformador:
- nombre
- modo_alterno
- descripción
- viva
En un servicio web RESTFul, se accede a cada recurso mediante una URL única, lo que significa que cada empleado tiene su URL única. Y, cada método del modelo se compone de un Verbo HTTP y un Alcance.
Verbo HTTP | Alcance | Semántica | URL |
---|---|---|---|
OBTENER | Transformador | Recuperar un solo transformador | http://hostlocal:8000/transformers/{id}/ |
OBTENER | Colección de transformador | Recupera todos los transformadores de la colección. | http://localhost:8000/transformadores/ |
CORREO | Colección de transformador | Crear un nuevo transformador en la colección. | http://localhost:8000/transformadores/ |
PONER | Transformador | Actualizar un transformador existente | http://hostlocal:8000/transformers/{id}/ |
PARCHE | Transformador | Actualizar parcialmente un transformador existente | http://hostlocal:8000/transformers/{id}/ |
ELIMINAR | Transformador | Eliminar un transformador existente | http://hostlocal:8000/transformers/{id}/ |
Entremos en la implementación del modelo Transformer en Django. Puede reemplazar el archivo Python models.py con el siguiente código:
Python3
from django.db import models class Transformer(models.Model): name = models.CharField(max_length=150, unique=True) alternate_mode = models.CharField( max_length=250, blank=True, null=True) description = models.CharField( max_length=500, blank=True, null=True) alive = models.BooleanField(default=False) class Meta: ordering = ('name',) def __str__(self): return self.name
El modelo Transformer es una subclase de la clase django.db.models.Model y define los atributos y una clase interna Meta. Tiene un atributo de ordenación que ordena el resultado en orden ascendente según el nombre. Hagamos las migraciones iniciales usando el siguiente comando (asegúrese de haber definido su aplicación (‘transformers.apps.TransformersConfig’) en INSTALLED_APPS en el archivo settings.py Python)
python manage.py hacer migraciones
Luego, aplique todas las migraciones generadas usando el siguiente comando:
python manage.py migrar
La aplicación de migraciones generadas creará una tabla de Transformador en la base de datos.
Creación de serializador
Cree un nuevo archivo Python serializers.py en la carpeta de su aplicación (transformadores) y agregue el siguiente código:
Python3
from rest_framework import serializers from transformers.models import Transformer class TransformerSerializer(serializers.ModelSerializer): class Meta: model = Transformer fields = "__all__"
Aquí, creamos una clase TransformerSerializer que hereda de rest_framework.serializers.ModelSerializer. Si desea profundizar en los diferentes tipos de serializados, puede consultar Django REST Framework (DRF) Serialization . Ahora es el momento de comenzar nuestro viaje hacia las vistas basadas en funciones. Comenzaremos con las vistas regulares de Django y luego aprovecharemos el decorador @api_view.
Vistas basadas en funciones
Las vistas de Django facilitan el procesamiento de requests HTTP y proporcionan respuestas HTTP. Al recibir una solicitud HTTP, Django crea una instancia de HttpRequest y se pasa como primer argumento a la función de vista. Esta instancia contiene verbos HTTP como GET, POST, PUT, PATCH o DELETE. La función de visualización comprueba el valor y ejecuta el código en función del verbo HTTP. Aquí, el código usa el decorador @csrf_exempt para configurar una cookie CSRF (falsificación de solicitud entre sitios). Esto hace posible publicar en esta vista desde clientes que no tendrán un token CSRF. Entremos en el proceso de implementación. Puede agregar el siguiente código en el archivo views.py.
Python3
from django.http import HttpResponse, JsonResponse from django.views.decorators.csrf import csrf_exempt from rest_framework.parsers import JSONParser from transformers.models import Transformer from transformers.serializers import TransformerSerializer @csrf_exempt def transformer_list(request): """ List all transformers, or create a new transformer """ if request.method == 'GET': transformer = Transformer.objects.all() serializer = TransformerSerializer(transformer, many=True) return JsonResponse(serializer.data, safe=False) elif request.method == 'POST': data = JSONParser().parse(request) serializer = TransformerSerializer(data=data) if serializer.is_valid(): serializer.save() return JsonResponse(serializer.data, status=201) return JsonResponse(serializer.errors, status=400) @csrf_exempt def transformer_detail(request, pk): try: transformer = Transformer.objects.get(pk=pk) except Transformer.DoesNotExist: return HttpResponse(status=404) if request.method == 'GET': serializer = TransformerSerializer(transformer) return JsonResponse(serializer.data) elif request.method == 'PUT': data = JSONParser().parse(request) serializer = TransformerSerializer(transformer, data=data) if serializer.is_valid(): serializer.save() return JsonResponse(serializer.data) return JsonResponse(serializer.errors, status=400) elif request.method == 'DELETE': transformer.delete() return HttpResponse(status=204)
Evaluemos el código. Aquí tenemos dos funciones.
- lista_de_transformadores()
- transformador_detalle()
lista_de_transformadores()
La función ransformer_list() es capaz de procesar dos verbos HTTP: GET y POST.
Si el verbo es GET , el código recupera todas las instancias del transformador.
if request.method == 'GET': transformer = Transformer.objects.all() serializer = TransformerSerializer(transformer, many=True) return JsonResponse(serializer.data, safe=False)
- Recupera todos los datos del transformador usando el método objects.all().
- Serializa las tareas mediante TransformerSerializer.
- Luego, los datos serializados se procesan usando JsonResponse() y devuelve el resultado
Nota : El argumento many=True especificado serializa varias instancias de Transformer.
Si el verbo es POST , el código crea un nuevo transformador. Aquí, los datos se proporcionan en formato JSON al redactar la solicitud HTTP.
elif request.method == 'POST': data = JSONParser().parse(request) serializer = TransformerSerializer(data=data) if serializer.is_valid(): serializer.save() return JsonResponse(serializer.data, status=201) return JsonResponse(serializer.errors, status=400)
- Utiliza JSONParser para analizar la solicitud,
- Serialice los datos analizados usando TransformerSerializer,
- Si los datos son válidos, se guardan en la base de datos y devuelven el resultado representado con el código de estado.
transformador_detalle()
La función transformer_detail() es capaz de procesar tres verbos HTTP: GET, PUT y DELETE. Si el verbo es GET, el código recupera una única instancia de transformador basada en la clave principal. Si el verbo es PUT, el código actualiza la instancia y la guarda en la base de datos, y si es DELETE, el código elimina la instancia de la base de datos.
Como siguiente paso, debemos enrutar las URL a las vistas. Debe crear un nuevo nombre de archivo de Python urls.py en la carpeta de la aplicación (transformadores) y agregar el siguiente código.
Python3
from django.urls import path from transformers import views urlpatterns = [ path('transformers/', views.transformer_list, name = 'employee-list'), path('transformers/<int:pk>/', views.transformer_detail, name = 'employee-detail'), ]
Ahora, actualicemos la configuración de la URL raíz. Puede agregar el siguiente código al archivo urls.py (la misma carpeta que tiene el archivo settings.py).
Python3
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('', include('transformers.urls')), ]
Ahora es el momento de redactar y enviar requests HTTP para probar nuestras vistas.
Vamos a crear una nueva entrada. El comando HTTPie es:
http POST :8000/transformers/ name=”Wheeljack” alternate_mode=”1977 Lancia Stratos Turbo” description=”Siempre inventando nuevas armas y artilugios” living=”Falso”
Producción
HTTP/1.1 201 Created Content-Length: 152 Content-Type: application/json Date: Mon, 25 Jan 2021 05:23:10 GMT Referrer-Policy: same-origin Server: WSGIServer/0.2 CPython/3.7.5 X-Content-Type-Options: nosniff X-Frame-Options: DENY { "alive": false, "alternate_mode": "1977 Lancia Stratos Turbo", "description": "Always inventing new weapons and gadgets", "id": 7, "name": "Wheeljack" }
Compartiendo la captura de pantalla del símbolo del sistema para su referencia
Actualicemos el campo vivo del transformador (id=7) a Verdadero. El comando HTTPie es:
http PUT :8000/transformers/7/ name=”Wheeljack” alternate_mode=”1977 Lancia Stratos Turbo” description=”Siempre inventando nuevas armas y artilugios” living=”Verdadero”
Producción
HTTP/1.1 200 OK Content-Length: 151 Content-Type: application/json Date: Mon, 25 Jan 2021 05:26:22 GMT Referrer-Policy: same-origin Server: WSGIServer/0.2 CPython/3.7.5 X-Content-Type-Options: nosniff X-Frame-Options: DENY { "alive": true, "alternate_mode": "1977 Lancia Stratos Turbo", "description": "Always inventing new weapons and gadgets", "id": 7, "name": "Wheeljack" }
Recuperemos todos los transformadores. El comando HTTPie es:
http OBTENER :8000/transformadores/
Producción
HTTP/1.1 200 OK Allow: GET, POST, OPTIONS Content-Length: 629 Content-Type: application/json Date: Mon, 25 Jan 2021 05:43:36 GMT Referrer-Policy: same-origin Server: WSGIServer/0.2 CPython/3.7.5 Vary: Accept, Cookie X-Content-Type-Options: nosniff X-Frame-Options: DENY [ { "alive": true, "alternate_mode": "1977 Lancia Stratos Turbo", "description": "Always inventing new weapons and gadgets", "id": 7, "name": "Wheeljack" }, { "alive": true, "alternate_mode": "1979 Porsche 924", "description": "Eager and Daring", "id": 5, "name": "Cliffjumper" }, { "alive": true, "alternate_mode": "1979 VW Beetle", "description": "Small, eager, and brave. Acts as a messenger, scout, and spy", "id": 3, "name": "Bumblebee" }, { "alive": false, "alternate_mode": "1979 Freightliner Semi", "description": "Optimus Prime is the strongest and most courageous and leader of all Autobots", "id": 1, "name": "Optimus Prime" } ]
Compartiendo la captura de pantalla del símbolo del sistema
@api_view
@api_view es un decorador en el módulo rest_framework.decorators , y es la clase base para todas las vistas del marco Django REST. Podemos proporcionar los verbos HTTP permitidos como el argumento http_methods_names (lista de strings) en el decorador @api_view . Si el servicio web RESTful recibe un verbo HTTP no compatible, el decorador devuelve una respuesta adecuada en lugar de un error inesperado en Django.
@api_view(http_method_names=['GET'])
Puede reemplazar el archivo views.py con el siguiente código.
Python3
from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework import status from transformers.models import Transformer from transformers.serializers import TransformerSerializer @api_view(['GET','POST']) def transformer_list(request): """ List all transformers, or create a new transformer """ if request.method == 'GET': transformer = Transformer.objects.all() serializer = TransformerSerializer(transformer, many=True) return Response(serializer.data) elif request.method == 'POST': serializer = TransformerSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @api_view(['GET','PUT','PATCH','DELETE']) def transformer_detail(request, pk): try: transformer = Transformer.objects.get(pk=pk) except Transformer.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': serializer = TransformerSerializer(transformer) return Response(serializer.data) elif request.method == 'PUT': serializer = TransformerSerializer(transformer, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) elif request.method == 'PATCH': serializer = TransformerSerializer(transformer, data=request.data, partial=True) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) elif request.method == 'DELETE': transformer.delete() return Response(status=status.HTTP_204_NO_CONTENT)
En el nuevo código, las funciones transformer_list y transformer_detail están envueltas con el decorador @api_vew. La función transformer_list admite los verbos GET y POST, mientras que el método transformer_detail admite los verbos GET, PUT, PATCH y DELETE. Estos verbos admitidos se pasan como parámetros de decorador para cada método. Aquí, eliminamos la clase rest_framework.parsers.JSONParser . De esta manera podemos dejar que el código funcione con diferentes analizadores. También reemplazamos la clase JSONResponse con una clase rest_framework.response.Response más genérica .
Ejecutemos el comando HTTPie con el verbo OPTIONS para enumerar los métodos y verbos admitidos en el método transformer_list.
http OPCIONES :8000/transformadores/
Producción
HTTP/1.1 200 OK Allow: GET, OPTIONS, POST Content-Length: 225 Content-Type: application/json Date: Mon, 25 Jan 2021 16:52:10 GMT Referrer-Policy: same-origin Server: WSGIServer/0.2 CPython/3.7.5 Vary: Accept, Cookie X-Content-Type-Options: nosniff X-Frame-Options: DENY { "description": "List all transformers, or create a new transformer", "name": "Transformer List", "parses": [ "application/json", "application/x-www-form-urlencoded", "multipart/form-data" ], "renders": [ "application/json", "text/html" ] }
Compartiendo la captura de pantalla del símbolo del sistema
La salida muestra los detalles del método transformer_list. Permite verbos GET, OPTIONS y POST HTTP. También muestra los diferentes análisis y representaciones que admite la función.
Veamos la función transformer_detail. El comando HTTPie es
http OPCIONES :8000/transformers/1/
Producción
HTTP/1.1 200 OK Allow: OPTIONS, DELETE, GET, PATCH, PUT Content-Length: 177 Content-Type: application/json Date: Mon, 25 Jan 2021 16:59:23 GMT Referrer-Policy: same-origin Server: WSGIServer/0.2 CPython/3.7.5 Vary: Accept, Cookie X-Content-Type-Options: nosniff X-Frame-Options: DENY { "description": "", "name": "Transformer Detail", "parses": [ "application/json", "application/x-www-form-urlencoded", "multipart/form-data" ], "renders": [ "application/json", "text/html" ] }
Puede notar que la función transformer_detail() es compatible con los verbos HTTP OPTIONS, DELETE, GET, PATCH y PUT. También muestra los diferentes análisis y representaciones que admite la función.
El decorador @api_view puede analizar diferentes tipos de contenido eligiendo el analizador apropiado. Del resultado anterior, podemos notar los diferentes analizadores admitidos en el decorador @api_view. Cuando usamos el decorador @api_view, automáticamente hace uso de la clase APIView y su configuración. De esta forma podremos utilizar los analizadores y renders.
El decorador @api_view ayuda al marco Django REST a examinar el encabezado Content-Type en el atributo de datos e identifica el analizador exacto para analizar la solicitud. También invoca la clase rest_framework.negotiation.DefaultContentNegotiation para seleccionar el renderizador adecuado para la solicitud.
Ahora es el momento de redactar y enviar diferentes requests HTTP. Vamos a crear una nueva entrada. El comando HTTPie es
http POST :8000/transformers/ name=”Prowl” alternate_mode=”1979 Nissan 280ZX Police Car” description=”Se esfuerza por encontrar la razón y la lógica en todo” living=”Falso”
Producción
HTTP/1.1 201 Created Allow: GET, POST, OPTIONS Content-Length: 149 Content-Type: application/json Date: Mon, 25 Jan 2021 16:18:56 GMT Referrer-Policy: same-origin Server: WSGIServer/0.2 CPython/3.7.5 Vary: Accept, Cookie X-Content-Type-Options: nosniff X-Frame-Options: DENY { "alive": false, "alternate_mode": "1979 Nissan 280ZX Police Car", "description": "Strives to find reason and logic in everything", "id": 10, "name": "Prowl" }
Compartiendo la captura de pantalla del símbolo del sistema
Actualicemos el valor del campo vivo a Verdadero. El comando HTTPie es:
http PARCHE: 8000/transformers/10/alive=”Verdadero”
Producción
HTTP/1.1 200 OK Allow: PATCH, PUT, DELETE, OPTIONS, GET Content-Length: 148 Content-Type: application/json Date: Mon, 25 Jan 2021 16:22:35 GMT Referrer-Policy: same-origin Server: WSGIServer/0.2 CPython/3.7.5 Vary: Accept, Cookie X-Content-Type-Options: nosniff X-Frame-Options: DENY { "alive": true, "alternate_mode": "1979 Nissan 280ZX Police Car", "description": "Strives to find reason and logic in everything", "id": 10, "name": "Prowl" }
Compartiendo la captura de pantalla del símbolo del sistema
Recuperemos todas las entradas. El comando HTTPie es:
http OBTENER :8000/transformadores/
Producción
HTTP/1.1 200 OK Allow: GET, POST, OPTIONS Content-Length: 739 Content-Type: application/json Date: Mon, 25 Jan 2021 16:23:52 GMT Referrer-Policy: same-origin Server: WSGIServer/0.2 CPython/3.7.5 Vary: Accept, Cookie X-Content-Type-Options: nosniff X-Frame-Options: DENY [ { "alive": true, "alternate_mode": "1979 Nissan 280ZX Police Car", "description": "Strives to find reason and logic in everything", "id": 10, "name": "Prowl" }, { "alive": true, "alternate_mode": "1977 Lancia Stratos Turbo", "description": "Always inventing new weapons and gadgets", "id": 7, "name": "Wheeljack" }, { "alive": true, "alternate_mode": "1979 Porsche 924", "description": "Eager and Daring", "id": 5, "name": "Cliffjumper" }, { "alive": true, "alternate_mode": "1979 VW Beetle", "description": "Small, eager, and brave. Acts as a messenger, scout, and spy", "id": 3, "name": "Bumblebee" }, { "alive": false, "alternate_mode": "1979 Freightliner Semi", "description": "Optimus Prime is the strongest and most courageous and leader of all Autobots", "id": 1, "name": "Optimus Prime" } ]
Compartiendo la captura de pantalla del símbolo del sistema
En esta sección, entendimos cómo codificar las vistas de Django para procesar la solicitud HTTP y devolver la respuesta HTTP. También nos dimos cuenta de la importancia de envolver nuestras vistas con el decorador @api_view. Finalmente, redactamos y enviamos diferentes requests, incluida la solicitud OPTIONS HTTP, que muestra los verbos, analizadores y renderizadores HTTP admitidos.
Publicación traducida automáticamente
Artículo escrito por SonuGeorge y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA