¿Cómo devolver JSON personalizado en Django REST Framework?

En este artículo, crearemos vistas basadas en clases y combinaremos esto con la clase de serializador para devolver la representación JSON para cada solicitud HTTP. Para nuestras vistas basadas en clases, haremos uso de un conjunto de vistas genéricas, que ayudan a lograr un código de líneas mínimo. 

  • Clases genéricas y conjuntos de vistas
  • Requests HTTP para interactuar con recursos de relaciones

Clases genéricas y conjuntos de vistas

Aprovecharemos las vistas de clases genéricas para implementar métodos get, post, delete, put y patch. Para esto, necesitamos hacer uso de dos vistas de clases genéricas del módulo rest_framework.generics . Están:

  • ListCreateAPIView
  • RecuperarActualizarDestruirAPIVer

La vista de clase ListCreateAPIView implementa el método get (recupera una lista de un conjunto de consultas) y el método post (crea una instancia de modelo). Y, la vista de clase RetrieveUpdateDestroyAPIView implementa get (recuperar una instancia de modelo), delete (eliminar una instancia de modelo), put (actualizar completamente una instancia de modelo) y parche (actualizar parcialmente una instancia de modelo).

En el marco Django REST, estas dos vistas genéricas se implementan como clases mixtas. ListCreateAPIView usa ListModelMixin y CreateModelMixin del módulo rest_framework.mixins y GenericAPIView del módulo rest_framework.generics . Veamos su declaración.

Python3

class ListCreateAPIView(mixins.ListModelMixin, 
                        mixins.CreateModelMixin, GenericAPIView):

RetrieveUpdateDestroyAPIView usa RetrieveModelMixin , UpdateModelMixin y DestroyModelMixin del módulo rest_framework.mixins y GenericAPIView del módulo rest_framework.generics . Veamos su declaración.

Python3

class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin, 
                                   mixins.UpdateModelMixin, 
                                   mixins.DestroyModelMixin, 
                                   GenericAPIView):

Ahora, regresemos a nuestro código de servicio web RESTFul y creemos el conjunto requerido de vistas basadas en la clase Django. Puede abrir el archivo Python restpi\robots\views.py y reemplazarlo con el siguiente código.

Python3

from django.shortcuts import render
  
from rest_framework import generics
from rest_framework.response import Response
from rest_framework.reverse import reverse
  
from robots.models import RobotCategory
from robots.models import Manufacturer
from robots.models import Robot
  
from robots.serializers import RobotCategorySerializer
from robots.serializers import ManufacturerSerializer
from robots.serializers import RobotSerializer
  
class ApiRoot(generics.GenericAPIView):
    name = 'api-root'
    def get(self, request, *args, **kwargs):
        return Response({
            'robot-categories': reverse(RobotCategoryList.name, request=request),
            'manufacturers': reverse(ManufacturerList.name, request=request),
            'robots': reverse(RobotList.name, request=request)
            })            
      
class RobotCategoryList(generics.ListCreateAPIView):
    queryset = RobotCategory.objects.all()
    serializer_class = RobotCategorySerializer
      
class RobotCategoryDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = RobotCategory.objects.all()
    serializer_class = RobotCategorySerializer
    name = 'robotcategory-detail'
  
class ManufacturerList(generics.ListCreateAPIView):
    queryset = Manufacturer.objects.all()
    serializer_class = ManufacturerSerializer
    name = 'manufacturer-list'
  
class ManufacturerDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Manufacturer.objects.all()
    serializer_class = ManufacturerSerializer
    name = 'manufacturer-detail'        
  
class RobotList(generics.ListCreateAPIView):
    queryset = Robot.objects.all()
    serializer_class = RobotSerializer
    name = 'robot-list'
  
class RobotDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Robot.objects.all()
    serializer_class = RobotSerializer
    name = 'robot-detail'

Aquí , RobotCategoryList , ManufacturerList y RobotList son las subclases de generics.ListCreateAPIView ; RobotCategoryDetail , ManufacturerDetail y RobotDetail son las subclases de generics.RetrieveUpdateDestroyAPIView. Cada subclase tiene un atributo de conjunto de consultas , un atributo serializer_class y un atributo de nombre . El atributo queryset almacena todos los objetos recuperados, el atributo serializer_class almacena la clase del serializador y el atributo name se usa para identificar cada vista.

Además de las vistas basadas en clases, puede observar una clase ApiRoot , que es una subclase de rest_framework.generics.GenericAPIView

Python3

class ApiRoot(generics.GenericAPIView):
    name = 'api-root'
    def get(self, request, *args, **kwargs):
        return Response({
            'robot-categories': reverse(RobotCategoryList.name, request=request),
            'manufacturers': reverse(ManufacturerList.name, request=request),
            'robots': reverse(RobotList.name, request=request)
            })

La clase ApiRoot crea un punto final para la raíz de nuestro servicio web RESTful que facilita la exploración de la colección de recursos. El método get definido en esta clase devuelve un objeto Response que tiene el nombre descriptivo y su URL. Aquí, devuelve el nombre descriptivo y la URL para la lista de categorías de robots, la lista de fabricantes y la lista de robots. 

A continuación, debemos especificar el patrón de URL en la expresión regular para ejecutar un método específico para una vista basada en clases definida en el archivo de Python views.py . La solicitud HTTP del cliente debe coincidir con esta expresión regular para ejecutar los métodos en el archivo views.py . Puede crear el archivo urls.py en restapi/robots y agregar el siguiente código.

Python3

from django.conf.urls import url
from robots import views
  
urlpatterns = [
    url(r'^robot-categories/$',
        views.RobotCategoryList.as_view(),
        name=views.RobotCategoryList.name),
    
    url(r'^robot-categories/(?P<pk>[0-9]+)$',
        views.RobotCategoryDetail.as_view(),
        name=views.RobotCategoryDetail.name),
    
    url(r'^manufacturers/$',
        views.ManufacturerList.as_view(),
        name=views.ManufacturerList.name),
      
    url(r'^manufacturers/(?P<pk>[0-9]+)$',
        views.ManufacturerDetail.as_view(),
        name=views.ManufacturerDetail.name),
    
    url(r'^robots/$',
        views.RobotList.as_view(),
        name=views.RobotList.name),
    
    url(r'^robots/(?P<pk>[0-9]+)$',
        views.RobotDetail.as_view(),
        name=views.RobotDetail.name),
    
    url(r'^$',
        views.ApiRoot.as_view(),
        name=views.ApiRoot.name),
]

Como paso final, debemos definir la configuración de la URL raíz. Puede abrir el archivo Python restapi/restapi/urls.py y reemplazarlo con el siguiente código:

Python3

from django.conf.urls import url, include
  
urlpatterns = [
    url(r'^', include('robots.urls')),
]

Requests HTTP para interactuar con recursos

Es hora de probar nuestro código componiendo y enviando varias requests HTTP. Aquí, aprovecharemos tanto el comando HTTPie como el comando CURL.

Crear una nueva categoría de robot

Redactemos y enviemos una solicitud HTTP Post para crear una nueva categoría de robot. El comando HTTPie es:

http POST :8000/robot-categories/ name=”Robots articulados” notes=”Flexibilidad, destreza y alcance hacen que los robots articulados sean ideales para tareas que abarcan planos no paralelos”

Producción:

Solicitud posterior de categoría de robot (HTTPie)

Vamos a crear otra categoría de robot usando el comando curl. 

curl -iX POST -H “Content-Type: application/json” -d “{\”name\”:\”SCARA Robots\”, \”notes\”:\”Un brazo robótico articulado de cumplimiento selectivo (SCARA) es una opción buena y rentable para realizar operaciones entre dos planos paralelos\”}” localhost:8000/robot-categories/

Producción:

Categoría de robot Solicitud POST (cURL)

Recuperar todas las categorías de robots

Compongamos una solicitud GET para recuperar todas las categorías de robots. El comando HTTPie es:

http:8000/categorías-robot/

Producción:

Solicitud GET de categoría de robot (comando de utilidad HTTPie)

El comando curl equivalente es

curl -iX GET localhost:8000/robot-categories/

Producción:

OBTENER solicitud (cURL)

Recuperar una sola categoría de robot

El comando HTTPie para recuperar una categoría de robot es:

http :8000/categorías-robot/1

Producción:

Solicitud GET (categoría única)

El comando curl equivalente es:

curl -iX GET localhost:8000/robot-categories/1

Crear un nuevo fabricante

Redactemos y enviemos una solicitud HTTP POST para crear un fabricante. El comando HTTPie es:

http :8000/manufacturers/ name=”FANUC Global” rating=4 notes=”El especialista en automatización y fabricante de robots industriales”

Producción:

HTTP/1.1 201 Creado

Permitir: GET, POST, HEAD, OPCIONES

Longitud del contenido: 219

Tipo de contenido: aplicación/json

Fecha: lunes, 16 de noviembre de 2020 06:36:12 GMT

Ubicación: http://localhost:8000/fabricantes/1

Referrer-Policy: mismo origen

Servidor: WSGIServer/0.2 CPython/3.7.5

Variar: Aceptar, Cookie

Opciones de tipo de contenido X: nosniff

Opciones de X-Frame: DENEGAR

{

    “fecha_de_entrada”: “2020-11-16T06:36:12.449074Z”,

    «robots»: [],

    “nombre”: “FANUC Global”,

    “notas”: “El especialista en automatización y fabricante de robots industriales”,

    «paquete»: 1,

    «puntuación»: 4,

    “url”: “http://localhost:8000/fabricantes/1”

}

Vamos a crear otro fabricante usando el comando curl.

curl -iX POST -H “Content-Type: application/json” -d “{\”name\”:\”ABB\”, \”rating\”:5, \”notes\”:\”Enfocado en electrificación , automatización industrial, robótica, automatización discreta y movimiento\”}” localhost:8000/fabricantes/

Producción:

HTTP/1.1 201 Creado

Fecha: lunes, 16 de noviembre de 2020 06:49:43 GMT

Servidor: WSGIServer/0.2 CPython/3.7.5

Tipo de contenido: aplicación/json

Ubicación: http://localhost:8000/fabricantes/2

Variar: Aceptar, Cookie

Permitir: GET, POST, HEAD, OPCIONES

Opciones de X-Frame: DENEGAR

Longitud del contenido: 242

Opciones de tipo de contenido X: nosniff

Referrer-Policy: mismo origen

{“url”:”http://localhost:8000/fabricantes/2″,”pk”:2,”nombre”:”ABB”,”calificación”:5,

“notes”:”Enfocado en Electrificación, Automatización Industrial, Robótica, Automatización Discreta 

y movimiento”,”entry_date”:”2020-11-16T06:49:43.108992Z”,”robots”:[]}

Recuperar un fabricante

Redactemos una solicitud para recuperar un fabricante. El comando HTTPie es:

http :8000/fabricantes/2

Producción:

Recuperar un solo fabricante

El comando curl equivalente es: 

curl -iX GET localhost:8000/fabricantes/2

Agregar detalles del robot

Hemos rellenado la categoría de robot y los detalles del fabricante. Ahora, compongamos y enviemos una solicitud POST para agregar detalles del robot. El comando HTTPie es 

http POST :8000/robots/ name=”FANUC M-710ic/50″ robot_category=”Articulated Robots” currency=”USD” price=37000 manufacturer=”FANUC Global” manufacturing_date=”2019-10-12 00:00:00.000000 +00:00″ add_details=”Ejes 6, Carga útil 50 KG, Alcance 2050 MM”

Producción:

Entrada de robot (comando HTTP Utility Pie)

Compongamos un comando curl para crear una nueva entrada.

curl -iX POST -H “Tipo de contenido: aplicación/json” -d “{\”nombre\”:\”SR-3iA\”, \”robot_category\”:\”SCARA Robots\”, \”moneda\ ”:\”USD\”, \”precio\”:37000, \”fabricante\”:\”FANUC Global\”, \”fecha_de_fabricación\”:\”2019-10-12 00:00:00.000000+00: 00\”, \”add_details\”:\”Eje 4, Carga útil 3 KG, Alcance 400 MM\”}” localhost:8000/robots/

Producción:

Agreguemos algunas entradas más en Robot. Los comandos HTTPie son:

http POST :8000/robots/ name=”IRB 120″ robot_category=”Articulated Robots” currency=”USD” price=14500 manufacturer=”ABB” manufacturing_date=”2020-05-10 00:00:00.000000+00:00″ add_details=”Ejes 6, Carga útil 3 KG, Alcance 0,58 m”

http POST :8000/robots/ nombre=”IRB 910SC” robot_category=”SCARA Robots” moneda=”USD” precio=25000 fabricante=”ABB” manufacturing_date=”2020-05-10 00:00:00.000000+00:00″ add_details=”Ejes 4, Carga útil 6 KG, Alcance 0,65 m”

Veamos la lista Robot, Categoría de robot y Fabricante. 

http:8000/robots/

Lista de robots

http:8000/categorías-robot/

Lista de categorías de robots

http :8000/fabricantes/

Lista de fabricantes

En las categorías de robots y la entrada del fabricante, puede notar que los robots se mencionan en su forma de URL. 

Recursos PUT, PATCH y DELETE

Ahora compongamos las requests PUT, PATCH y DELETE. Agregaremos una nueva categoría de robot (Categoría de prueba) y fabricante (Fabricante de prueba). El comando HTTPie de la siguiente manera:

http POST: 8000/robot-categories/ nombre = «Categoría de prueba» notas = «Prueba»

http POST: 8000/fabricantes/ nombre = «Fabricante de prueba» calificación = 1 notas = «Prueba»

Agreguemos algunos robots que pertenecen a la categoría de prueba y al fabricante de prueba . El comando HTTPie de la siguiente manera:

http POST :8000/robots/ name=”PRUEBA 1″ robot_category=”Categoría de prueba” moneda=”USD” precio=37000 fabricante=”Fabricante de prueba” manufacturing_date=”2019-10-12 00:00:00.000000+00:00 ″ agregar_detalles=”Prueba”

http POST :8000/robots/ nombre=”PRUEBA 2″ robot_category=”Categoría de prueba” moneda=”USD” precio=37000 fabricante=”Fabricante de prueba” manufacturing_date=”2019-10-12 00:00:00.000000+00:00 ″ agregar_detalles=”Prueba”

http POST :8000/robots/ nombre=”PRUEBA 3″ robot_category=”Categoría de prueba” moneda=”USD” precio=37000 fabricante=”Fabricante de prueba” manufacturing_date=”2019-10-12 00:00:00.000000+00:00 ″ add_details=”Prueba”

Verifiquemos las entradas en la base de datos usando el siguiente comando psql. 

seleccione * de robots_robot;

Producción:

Puede notar que se agregan nuevas entradas a nuestra base de datos. 

PONER verbo HTTP

Ahora vamos a editar la última entrada llamada TEST 3, que tiene 11 como clave principal, usando el verbo PUT HTTP .

El comando HTTPUtility Pie es:

http PUT :8000/robots/11 nombre=”PRUEBA 3″ robot_category=”Categoría de prueba” moneda=”USD” precio=12000 fabricante=”Fabricante de prueba” manufacturing_date=”2020-10-12 00:00:00.000000+00: 00″ agregar_detalles=”Prueba3″

Producción:

El comando curl equivalente es

curl -iX PUT -H “Tipo de contenido: aplicación/json” -d “{\”nombre\”:\”PRUEBA 3\”, \”categoría_robot\”:\”Categoría de prueba\”, \”moneda\” :\”USD\”, \”precio\”:12000, \”fabricante\”:\”Fabricante de prueba\”, \”fecha_de_fabricación\”:\”2020-10-12 00:00:00.000000+00:00 \”, \”agregar_detalles\”:\”Prueba3\”}” localhost:8000/robots/11

PARCHE HTTP Verbo

Editemos parcialmente el recurso que tiene la clave principal 11. El comando HTTPie para la solicitud PATCH es:

http PATCH :8000/robots/11 precio=15000 add_details=”Test3 Patch”

Producción:

El comando curl equivalente es:

curl -iX PATCH -H “Content-Type: application/json” -d “{ \”price\”:15000, \”add_details\”:\”Test3 Patch\”}” localhost:8000/robots/11

ELIMINAR Verbo HTTP

Ahora, eliminemos la entrada que tiene la clave principal 11 usando DELETE HTTP Verb. El comando HTTPie es:

http ELIMINAR: 8000/robots/11

Producción:

El comando curl equivalente es 

curl -iX ELIMINAR localhost:8000/robots/11

Ahora, debemos verificar qué sucede si se elimina una categoría de robot. De acuerdo con nuestro código, si se elimina una categoría, también se deben borrar todos los robots que pertenecen a esa categoría en particular. Eliminemos nuestra categoría de prueba ( la identificación principal 3). El comando HTTPie es

http ELIMINAR: 8000/robot-categories/3

Producción:

Miremos la mesa del robot. En total, agregamos 3 robots ( Prueba 1, Prueba 2 y Prueba 3 ) que pertenecen a la Categoría de prueba . El robot que tiene la identificación principal 11 ( Prueba 3 ) ya se eliminó mediante la solicitud de eliminación. Los dos robots restantes con ID principal 9 (Prueba 1) y 10 (Prueba 2) existen en la base de datos. Dado que eliminamos la categoría de prueba, automáticamente los otros dos robots se borrarán de la tabla. Verifiquemos la base de datos usando el comando psql.

seleccione * de robots_robot;

Producción:

Puede notar que los robots que pertenecen a la categoría de prueba se borran con éxito. Esto es posible con la ayuda del código, on_delete=models.CASCADE, mencionado al definir la categoría de robot como clave externa en el modelo de robot.

Resumen

En este artículo, aprendimos sobre vistas de clases genéricas para implementar requests HTTP. Para esto, usamos dos vistas de clases genéricas del módulo rest_framework.generics, ListCreateAPIView y RetrieveUpdateDestroyAPIView . Y también compusimos diferentes requests HTTP para interactuar con recursos relacionados.

Publicación traducida automáticamente

Artículo escrito por SonuGeorge y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *