Las vistas basadas en clases ayudan a componer fragmentos de comportamiento reutilizables. Django REST Framework proporciona varias vistas prediseñadas que nos permiten reutilizar la funcionalidad común y mantener nuestro código SECO. En esta sección, profundizaremos en las diferentes vistas basadas en clases en Django REST Framework.
Este artículo asume que ya está familiarizado con Django y Django REST Framework.
Verificar –
APIView
La clase APIView proporciona el comportamiento comúnmente requerido para la lista estándar y las vistas detalladas. Con la clase APIView, podemos reescribir la vista raíz como una vista basada en clases. Proporcionan métodos de acción como get(), post(), put(), patch() y delete() en lugar de definir los métodos del controlador.
Creando vistas usando APIView
Echemos un vistazo a cómo crear vistas usando APIView. El módulo de archivo views.py de la siguiente manera:
Python3
from django.shortcuts import render from django.http import Http404 from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from transformers.models import Transformer from transformers.serializers import TransformerSerializer class TransformerList(APIView): """ List all Transformers, or create a new Transformer """ def get(self, request, format=None): transformers = Transformer.objects.all() serializer = TransformerSerializer(transformers, many=True) return Response(serializer.data) def post(self, request, format=None): 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) class TransformerDetail(APIView): """ Retrieve, update or delete a transformer instance """ def get_object(self, pk): # Returns an object instance that should # be used for detail views. try: return Transformer.objects.get(pk=pk) except Transformer.DoesNotExist: raise Http404 def get(self, request, pk, format=None): transformer = self.get_object(pk) serializer = TransformerSerializer(transformer) return Response(serializer.data) def put(self, request, pk, format=None): transformer = self.get_object(pk) 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) def patch(self, request, pk, format=None): transformer = self.get_object(pk) 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) def delete(self, request, pk, format=None): transformer = self.get_object(pk) transformer.delete() return Response(status=status.HTTP_204_NO_CONTENT)
El código es similar a las vistas regulares de Django, pero hay una mejor separación entre los diferentes métodos HTTP.
- El método get() procesa la solicitud HTTP GET
- El método post() procesa la solicitud HTTP POST
- El método put() procesa la solicitud HTTP PUT
- El método patch() procesa la solicitud HTTP PATCH
- El método delete() procesa la solicitud HTTP DELETE
Establecimiento de la configuración de URL
Dado que estamos utilizando vistas basadas en clases, la forma en que mencionamos las vistas en la ruta del archivo urls.py es ligeramente diferente. Cree un nuevo archivo llamado urls.py (si no existe) en la carpeta de la aplicación (transformadores) y agregue el siguiente código
Python3
from django.urls import path from rest_framework.urlpatterns import format_suffix_patterns from transformers import views urlpatterns = [ path('transformers/', views.TransformerList.as_view()), path('transformers/<int:pk>/', views.TransformerDetail.as_view()), ] urlpatterns = format_suffix_patterns(urlpatterns)
A continuación, establezca la configuración de la URL raíz. Puede abrir urls.py (la misma carpeta donde se encuentra el archivo settings.py) y agregar el siguiente código
Python3
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('', include('transformers.urls')), ]
Redacción y envío de requests HTTP
1. Crea una nueva entrada –
El comando HTTPie es:
http POST :8000/transformers/ name=”Optimus Prime” alternate_mode=”1979 Freightliner Semi” description=”Optimus Prime es el más fuerte y valiente de todos los Autobots, también es su líder” living=”True”
Producción
HTTP/1.1 201 Created Allow: GET, POST, HEAD, OPTIONS Content-Length: 194 Content-Type: application/json Date: Sat, 23 Jan 2021 03:48:46 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 Freightliner Semi", "description": "Optimus Prime is the strongest and most courageous of all Autobots, he is also their leader", "id": 1, "name": "Optimus Prime" }
Compartiendo la captura de pantalla del símbolo del sistema para su referencia:
2. Recuperar una entrada existente
El valor pk de Optimus Prime es 1. Pasemos el valor pk y recuperemos los detalles
El comando HTTPie es:
http OBTENER: 8000/transformadores/1/
Producción
HTTP/1.1 200 OK Allow: GET, HEAD, OPTIONS Content-Length: 194 Content-Type: application/json Date: Sat, 23 Jan 2021 03:50:42 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 Freightliner Semi", "description": "Optimus Prime is the strongest and most courageous of all Autobots, he is also their leader", "id": 1, "name": "Optimus Prime" }
Compartiendo la captura de pantalla del símbolo del sistema para su referencia
3. Actualizar una entrada existente
Actualicemos el campo llamado Alive configurándolo en False. El comando HTTPie es:
http PUT :8000/transformers/1/ name=”Optimus Prime” alternate_mode=”1979 Freightliner Semi” description=”Optimus Prime es el más fuerte y valiente de todos los Autobots, también es su líder” living=”Falso”
Producción
HTTP/1.1 200 OK Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS Content-Length: 195 Content-Type: application/json Date: Sat, 23 Jan 2021 04:22:30 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 Freightliner Semi", "description": "Optimus Prime is the strongest and most courageous of all Autobots, he is also their leader", "id": 1, "name": "Optimus Prime" }
Compartiendo la captura de pantalla del símbolo del sistema para su referencia
4. Actualizar parcialmente una entrada existente
Actualicemos parcialmente el campo llamado descripción. El comando HTTPie es:
http PATCH :8000/transformers/1/ description=”Optimus Prime es el más fuerte, valiente y líder de todos los Autobots”
Producción
HTTP/1.1 200 OK Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS Content-Length: 181 Content-Type: application/json Date: Sat, 23 Jan 2021 04:32:40 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 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
5. Eliminar una entrada existente
Crearemos una nueva entrada y la eliminaremos. Vamos a crear una entrada de ‘Prueba’ usando el siguiente comando HTTPie:
http POST :8000/transformers/ nombre=”Prueba”
Producción
HTTP/1.1 201 Created Allow: GET, POST, HEAD, OPTIONS Content-Length: 77 Content-Type: application/json Date: Sat, 23 Jan 2021 04:34:41 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": null, "description": null, "id": 2, "name": "Test" }
Ahora eliminemos la entrada ‘Prueba’ (pk =2). El comando HTTPie para eliminar la entrada es
http ELIMINAR: 8000/transformadores/2/
Producción
HTTP/1.1 204 No Content Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS Content-Length: 0 Date: Sat, 23 Jan 2021 04:35:06 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
Compartiendo la captura de pantalla del símbolo del sistema
mezclas
Las clases mixtas nos permiten componer fragmentos de comportamiento reutilizables. Se pueden importar desde rest_framework.mixins. Analicemos los diferentes tipos de clases mixtas.
- ListModelMixin : proporciona un método .list(request, *args, **kwargs) para enumerar un conjunto de consultas. Si se completa el conjunto de consultas, el cuerpo de la respuesta tiene una respuesta 200 OK con una representación serializada del conjunto de consultas.
- CreateModelMixin : proporciona un método .create(request, *args, **kwargs) para crear y guardar una nueva instancia de modelo. Si se crea el objeto, el cuerpo de la respuesta tiene una respuesta 201 Creado , con una representación serializada del objeto. Si no es válido, devuelve una respuesta de solicitud incorrecta 400 con los detalles del error.
- RetrieveModelMixin : proporciona un método .retrieve(request, *args, **kwargs) para devolver una instancia de modelo existente en una respuesta. Si se puede recuperar un objeto, el cuerpo de la respuesta tiene una respuesta 200 OK , con una representación serializada del objeto. De lo contrario, devolverá un 404 No encontrado .
- UpdateModelMixin : proporciona un método .update(request, *args, **kwargs) para actualizar y guardar una instancia de modelo existente. También proporciona un método .partial_update(request, *args, **kwargs) para actualizar parcialmente una instancia de modelo existente. . Si el objeto se actualiza, el cuerpo de la respuesta tiene una respuesta 200 OK , con una representación serializada del objeto. De lo contrario, se devolverá la respuesta 400 Bad Request con los detalles del error.
- DestroyModelMixin : proporciona un método .destroy(request, *args, **kwargs) para eliminar una instancia de modelo existente. Si se elimina un objeto, el cuerpo de la respuesta tiene una respuesta 204 Sin contenido ; de lo contrario, devolverá un 404 No encontrado .
Nota: Usaremos GenericAPIView para crear nuestras vistas y agregar Mixins.
Creación de vistas usando Mixins
Echemos un vistazo a cómo podemos hacer uso de las clases de Mixin. El módulo de archivo views.py de la siguiente manera:
Python3
from rest_framework import mixins from rest_framework import generics from transformers.models import Transformer from transformers.serializers import TransformerSerializer class TransformerList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Transformer.objects.all() serializer_class = TransformerSerializer def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) class TransformerDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView): queryset = Transformer.objects.all() serializer_class = TransformerSerializer def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) def patch(self, request, *args, **kwargs): return self.partial_update(request, *args, **kwargs) def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs)
Aquí, la clase GenericAPIView proporciona la funcionalidad principal y le estamos agregando clases mixtas. Queryset y serializer_class son los atributos básicos de la clase GenericAPIView . El atributo queryset se usa para devolver objetos desde esta vista y el atributo serializer_class se usa para validar, deserializar entradas y serializar salidas.
En la clase TransformerList, utilizamos clases mixtas que proporcionan acciones .list() y .create() y vinculan las acciones a los métodos get() y post(). En la clase TransformerDetail hacemos uso de clases mixtas que proporcionan .retrieve(), .update(), .partial_update() y . acciones destroy() y vincule las acciones a los métodos get(), put(), patch() y delete().
Redacción y envío de requests HTTP
1. Crea una nueva entrada
El comando HTTPie es
http POST :8000/transformers/ name=”Bumblebee” alternate_mode=”1979 VW Beetle” description=”Pequeño, entusiasta y valiente, Bumblebee actúa como mensajero, explorador y espía” living=”Verdadero”
Producción
HTTP/1.1 201 Created Allow: GET, POST, HEAD, OPTIONS Content-Length: 161 Content-Type: application/json Date: Sat, 23 Jan 2021 04:58:26 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 VW Beetle", "description": "Small, eager, and brave, Bumblebee acts as a messenger, scout, and spy", "id": 3, "name": "Bumblebee" }
2. Recuperar todas las entradas
El comando HTTPie es
http OBTENER :8000/transformadores/
Producción
HTTP/1.1 200 OK Allow: GET, POST, HEAD, OPTIONS Content-Length: 345 Content-Type: application/json Date: Sat, 23 Jan 2021 04:59:42 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 VW Beetle", "description": "Small, eager, and brave, Bumblebee 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 para su referencia
Vistas genéricas basadas en clases
Para hacer uso de vistas genéricas basadas en clases, las clases de vista deben importarse desde rest_framework.generics.
- CreateAPIView : proporciona un controlador de método de publicación y se usa para puntos finales de solo creación. CreateAPIView amplía GenericAPIView y CreateModelMixin
- ListAPIView : proporciona un controlador de método get y se usa para puntos finales de solo lectura para representar una colección de instancias de modelo. ListAPIView amplía GenericAPIView y ListModelMixin.
- RetrieveAPIView : proporciona un controlador de método get y se usa para puntos finales de solo lectura para representar una sola instancia de modelo. RetrieveAPIView amplía GenericAPIView y RetrieveModelMixin.
- DestroyAPIView : proporciona un controlador de método de eliminación y se usa para puntos finales de solo eliminación para una sola instancia de modelo. DestroyAPIView amplía GenericAPIView y DestroyModelMixin.
- UpdateAPIView : proporciona controladores de métodos de colocación y parches y se usa para puntos finales de solo actualización para una sola instancia de modelo. UpdateAPIView amplía GenericAPIView y UpdateModelMixin.
- ListCreateAPIView : proporciona controladores de métodos de obtención y publicación y se usa para puntos finales de lectura y escritura para representar una colección de instancias de modelo. ListCreateAPIView amplía GenericAPIView, ListModelMixin y CreateModelMixin.
- RetrieveUpdateAPIView : proporciona controladores de métodos get, put y patch. Se utiliza para leer o actualizar puntos finales para representar una sola instancia de modelo. RetrieveUpdateAPIView amplía GenericAPIView, RetrieveModelMixin y UpdateModelMixin.
- RetrieveDestroyAPIView : proporciona controladores de métodos de obtención y eliminación y se usa para leer o eliminar puntos finales para representar una sola instancia de modelo. RetrieveDestroyAPIView amplía GenericAPIView, RetrieveModelMixin y DestroyModelMixin.
- RetrieveUpdateDestroyAPIView : proporciona controladores de métodos get, put, patch y delete. Se utiliza para puntos finales de lectura, escritura y eliminación para representar una sola instancia de modelo. Extiende GenericAPIView, RetrieveModelMixin, UpdateModelMixin y DestroyModelMixin.
Creación de vistas mediante vistas genéricas basadas en clases
Echemos un vistazo a cómo podemos hacer uso de las clases de Mixin. Aquí aprovecharemos ListCreateAPIView y RetrieveUpdateDestroyAPIView. El módulo de archivo views.py de la siguiente manera:
Python3
from rest_framework import generics from transformers.models import Transformer from transformers.serializers import TransformerSerializer class TransformerList(generics.ListCreateAPIView): queryset = Transformer.objects.all() serializer_class = TransformerSerializer class TransformerDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Transformer.objects.all() serializer_class = TransformerSerializer
Puede notar que pudimos evitar una gran cantidad de código repetitivo. Estas vistas genéricas combinan fragmentos de comportamiento reutilizables de las clases mixtas. Veamos la declaración de ListCreateAPIView y RetrieveUpdateDestroyAPIView:
class ListCreateAPIView(mixins.ListModelMixin, mixins.CreateModelMixin, GenericAPIView): ...... class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, GenericAPIView): ......
Redacción y envío de requests HTTP
1. Crea una nueva entrada
El comando HTTPie es
http POST :8000/transformers/ name=”Cliffjumper” alternate_mode=”1979 Porsche 924″ description=”Su entusiasmo y audacia no tienen igual” living=”True”
Producción
HTTP/1.1 201 Created Allow: GET, POST, HEAD, OPTIONS Content-Length: 133 Content-Type: application/json Date: Sat, 23 Jan 2021 05:28:45 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 Porsche 924", "description": "His eagerness and daring have no equal", "id": 5, "name": "Cliffjumper" }
Compartiendo la captura de pantalla del símbolo del sistema para su referencia
2. Actualizar una entrada existente
El comando HTTPie es
http PUT :8000/transformers/5/ name=”Cliffjumper” alternate_mode=”1979 Porsche 924″ description=”Ansioso y audaz” vivo=”Verdadero”
Producción
HTTP/1.1 200 OK Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS Content-Length: 111 Content-Type: application/json Date: Sat, 23 Jan 2021 05:35:39 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 Porsche 924", "description": "Eager and Daring", "id": 5, "name": "Cliffjumper" }
Compartiendo la captura de pantalla del símbolo del sistema para su referencia
3. Actualizar parcialmente una entrada existente
http PARCHE: 8000/transformers/3/alive=”Verdadero”
Producción
HTTP/1.1 200 OK Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS Content-Length: 151 Content-Type: application/json Date: Sat, 23 Jan 2021 05:37:54 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 VW Beetle", "description": "Small, eager, and brave. Acts as a messenger, scout, and spy", "id": 3, "name": "Bumblebee" }
Compartiendo la captura de pantalla del símbolo del sistema para su referencia
En esta sección, exploramos diferentes tipos de vistas basadas en clases proporcionadas por Django REST Framework. Implementamos vistas usando APIView y explicamos diferentes tipos de clases mixtas. Finalmente, revelamos varios tipos de vistas genéricas basadas en clases y demostramos cómo evitan una gran cantidad de código repetitivo.
Publicación traducida automáticamente
Artículo escrito por SonuGeorge y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA