La función de API navegable en el marco Django REST genera una salida HTML para diferentes recursos. Facilita la interacción con el servicio web RESTful a través de cualquier navegador web. Para habilitar esta función, debemos especificar texto/html para la clave de tipo de contenido en el encabezado de la solicitud. Nos ayuda a utilizar navegadores web para navegar a través de la API y puede realizar diferentes requests HTTP. En esta sección, trabajaremos con la función de API navegable en el marco de la API REST de Django.
Cree un proyecto simple para demostrar las API navegables:
Vamos a crear modelos, serializadores y vistas necesarios para nuestros robots de aplicaciones.
Creación de modelos
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 los siguientes modelos:
- RobotCategory (Categorías de robots)
- Fabricante (Detalles del fabricante)
- Robot (Detalles del robot)
El modelo RobotCategory requiere:
- Nombre de categoría de robot
El modelo de Fabricante requiere:
- Nombre del Fabricante
El modelo de Robot requiere:
- Nombre del robot
- Una clave externa al modelo RobotCategory
- Una clave externa al modelo Manufacturer
- Divisa
- Precio
- Fecha de fabricación
Analicemos el verbo HTTP, la semántica de alcance en nuestro servicio web robots Restful.
Verbo HTTP | Alcance | Semántica | URL |
---|---|---|---|
OBTENER | Categoría de robots | Recuperar una categoría de robot | http://localhost:8000/robocategory/{id}/ |
OBTENER | Colección de la categoría Robot | Recupera todas las categorías de robots de la colección. | http://localhost:8000/robocategoría/ |
CORREO | Colección de la categoría Robot | Crear una nueva categoría de robot en la colección | http://localhost:8000/robocategory/{id}/ |
PONER | Categoría de robots | Actualizar una categoría de robot | http://localhost:8000/robocategory/{id}/ |
ELIMINAR | Categoría de robots | Eliminar una categoría de robot | http://localhost:8000/robocategory/{id}/ |
OBTENER | Fabricante | Recuperar un fabricante | http://localhost:8000/fabricante/{id}/ |
OBTENER | Colección de fabricante | Recuperar todos los fabricantes de la colección. | http://localhost:8000/fabricante/ |
CORREO | Colección de fabricante | Crear un fabricante en la colección | http://localhost:8000/fabricante/{id}/ |
PONER | Fabricante | Actualizar un fabricante | http://localhost:8000/fabricante/{id}/ |
ELIMINAR | Fabricante | Eliminar un fabricante | http://localhost:8000/fabricante/{id}/ |
OBTENER | Robot | recuperar un robot | http://localhost:8000/robot/{id}/ |
OBTENER | colección de robots | Recupera todos los robots de la colección. | http://localhost:8000/robot/ |
CORREO | colección de robots | Crear un robot en la colección. | http://localhost:8000/robot/{id}/ |
PONER | Robot | Actualizar un robot | http://localhost:8000/robot/{id}/ |
ELIMINAR | Robot | Eliminar un robot | http://localhost:8000/robot/{id}/ |
Vamos a crear los modelos para la categoría de robot, el fabricante, el robot y sus relaciones. Puede agregar el siguiente código en el archivo models.py.
Python3
from django.db import models class RobotCategory(models.Model): name = models.CharField(max_length=150, unique=True) class Meta: ordering = ('name',) def __str__(self): return self.name class Manufacturer(models.Model): name = models.CharField(max_length=150, unique=True) class Meta: ordering = ('name',) def __str__(self): return self.name class Robot(models.Model): CURRENCY_CHOICES = ( ('INR', 'Indian Rupee'), ('USD', 'US Dollar'), ('EUR', 'Euro'), ) name = models.CharField(max_length=150, unique=True) robot_category = models.ForeignKey( RobotCategory, related_name='robots', on_delete=models.CASCADE) manufacturer = models.ForeignKey( Manufacturer, related_name='robots', on_delete=models.CASCADE) currency = models.CharField( max_length=3, choices= CURRENCY_CHOICES, default='INR') price = models.IntegerField() manufacturing_date = models.DateTimeField() class Meta: ordering = ('name',) def __str__(self): return self.name
Aquí tenemos tres clases que son subclases de la clase django.db.models.Model:
- RobotCategoría
- Fabricante
- Robot
La clase Robot tiene una relación de muchos a uno con el modelo RobotCategory y el modelo Manufacturer. Esta relación se logra haciendo uso de la clase django.db.models.ForeignKey. El código de la siguiente manera:
robot_category = models.ForeignKey( RobotCategory, related_name='robots', on_delete=models.CASCADE) manufacturer = models.ForeignKey( Manufacturer, related_name='robots', on_delete=models.CASCADE)
El argumento related_name crea una relación inversa. Aquí, el valor ‘robots’ en related_name crea una relación inversa de RobotCategory a Robot y Manufacturer a Robot. Esto facilita la búsqueda de todos los robots que pertenecen a una categoría de robots y también en función del fabricante.
A continuación, puede realizar el proceso de migración y aplicar toda la migración generada. Puedes usar los siguientes comandos
python manage.py hacer migraciones
python manage.py migrar
Creación de serializadores
Ahora, necesitamos serializar las instancias de RobotCategory, Manufacturer y Robot. Aquí, usaremos HyperlinkedModelSerializer para manejar las relaciones del modelo. Puede consultar el tema Relaciones del serializador DRF para comprenderlo en detalle.
Python3
from rest_framework import serializers from robots.models import RobotCategory, Manufacturer, Robot class RobotCategorySerializer(serializers.HyperlinkedModelSerializer): robots = serializers.HyperlinkedRelatedField( many=True, read_only=True, view_name='robot-detail') class Meta: model = RobotCategory fields = '__all__' class ManufacturerSerializer(serializers.HyperlinkedModelSerializer): robots = serializers.HyperlinkedRelatedField( many=True, read_only=True, view_name='robot-detail') class Meta: model = Manufacturer fields = '__all__' class RobotSerializer(serializers.HyperlinkedModelSerializer): robot_category = serializers.SlugRelatedField( queryset=RobotCategory.objects.all(), slug_field='name') manufacturer = serializers.SlugRelatedField( queryset=Manufacturer.objects.all(), slug_field='name') currency = serializers.ChoiceField( choices=Robot.CURRENCY_CHOICES) currency_name = serializers.CharField( source='get_currency_display', read_only=True) class Meta: model = Robot fields = '__all__'
Las clases RobotCategorySerializer y ManufacturerSerializer son subclases de la clase HyperlinkedModelSerializer, y la relación inversa (RobotCategory a Robot y Manufacturer a Robot) se representa mediante HyperlinkedRelatedField con muchos y atributos de solo lectura establecidos en True. view_name (robot-detail) permite que la función de API navegable proporcione una función de clic para que el usuario represente el hipervínculo.
La clase RobotSerializer también es una subclase de la clase HyperlinkedModelSerializer. La clase RobotSerializer declara dos atributos, robot_category y manufacturer, que contiene una instancia de serializers.SlugRelatedField. Un campo relacionado con Slug representa una relación mediante un atributo de slug único.
Creación de vistas
Hagamos uso de vistas genéricas basadas en clases proporcionadas por Django REST Framework para procesar las requests HTTP y proporcionar las respuestas HTTP adecuadas. Puede consultar las vistas basadas en la clase DRF para obtener una explicación detallada.
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, Manufacturer, Robot from robots.serializers import RobotCategorySerializer, \ ManufacturerSerializer, 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 name = 'robotcategory-list' 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í, nuestras clases de vista se importan desde rest_framework.generics y aprovechamos dos vistas genéricas basadas en clases: ListCreateAPIView y RetrieveUpdateDestroyAPIView.
Puede notar que una clase ApiRoot, una subclase de generics.GenericAPIView, crea un punto final para la raíz de nuestro servicio web. Facilita la exploración de los recursos con la función de API explorable.
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) })
El método get devuelve un objeto Response (como un par de strings clave/valor) que tiene el nombre descriptivo de la vista y su URL.
Configuración de configuración de URL
Vaya a la carpeta de aplicaciones (robots) y cree un nuevo archivo llamado archivo urls.py. Puede agregar el siguiente código:
Python3
from django.urls import path from robots import views urlpatterns = [ path('robocategory/', views.RobotCategoryList.as_view(), name='robotcategory-list'), path('robocategory/<int:pk>/', views.RobotCategoryDetail.as_view(), name='robotcategory-detail'), path('manufacturer/', views.ManufacturerList.as_view(), name='manufacturer-list'), path('manufacturer/<int:pk>/', views.ManufacturerDetail.as_view(), name='manufacturer-detail'), path('robot/', views.RobotList.as_view(), name='robot-list'), path('robot/<int:pk>/', views.RobotDetail.as_view(), name='robot-detail'), path('', views.ApiRoot.as_view(), name=views.ApiRoot.name) ]
Define el patrón de URL que debe coincidir en la solicitud para ejecutar el método particular para una vista basada en clases definida en el archivo views.py. Ahora tenemos que establecer la configuración de la URL raíz. Puede agregar el siguiente código:
Python3
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('', include('robots.urls')), ]
¿Cómo realizar requests a la API utilizando la API navegable?
Redactemos y enviemos requests HTTP para generar contenido de texto/html en la respuesta. El servicio web RESTFul utiliza la clase BrowsableAPIRenderer para generar contenido HTML. El comando HTTPie para aceptar texto/html de la siguiente manera:
http -v :8000/robot/ “Aceptar:texto/html”
Compartiendo la captura de pantalla del símbolo del sistema para su referencia
Antes de utilizar la API navegable, creemos una nueva entrada para Categoría de robot, Fabricante y Robot mediante el comando HTTPie. El comando de la siguiente manera:
http POST :8000/robocategory/ name=”Robots Articulados”
http POST :8000/fabricante/nombre=”Fanuc”
http POST :8000/robot/ name=”FANUC M-710ic/50″ robot_category=”Robots articulados” fabricante=”Fanuc” moneda=”USD” precio=37000 manufacturing_date=”2019-10-12 00:00:00+ 00:00″
OBTENER solicitud HTTP
Ahora, exploremos el servicio web Restful de ‘robots’ usando un navegador. Puede utilizar la siguiente URL.
http://localhost:8000/
Compartiendo la captura de pantalla del navegador para su referencia
Puede hacer clic en el enlace que corresponde a las categorías de robots, fabricantes y robots y verificar los datos. Compartir la captura de pantalla del navegador que muestra el resultado de robots (http://localhost:8000/robot/)
POST Solicitud HTTP
A continuación, creemos una nueva categoría de robot. Puede navegar por el siguiente enlace y desplazarse hacia abajo.
http://localhost:8000/robocategoría/
Compartiendo la captura de pantalla del navegador para su referencia
Puede escribir el nombre de la nueva categoría de robot y hacer clic en el botón POST. Aquí, se muestra en formato HTML. Si elige Datos sin procesar, seleccione el tipo de medio como aplicación/json, complete el nuevo nombre de categoría de robot en el campo de nombre y haga clic en el botón POST. Compartiendo la captura de pantalla para su referencia.
Compartir la captura de pantalla de salida
Vamos a crear un nuevo fabricante, puede navegar por la siguiente URL
http://localhost:8000/fabricante/
Compartiendo la captura de pantalla del navegador
Puede escribir el nombre del fabricante (ABB) y hacer clic en el botón POST. El navegador muestra la salida como se muestra a continuación
Finalmente, creemos una nueva entrada para el robot. Puede navegar por la siguiente URL y desplazarse hacia abajo.
http://localhost:8000/robot/
Completemos los datos. Compartiendo la captura de pantalla del navegador para su referencia
Aquí, puede notar que la categoría Robot, Fabricación y Moneda son campos desplegables. Después de completar las entradas, puede hacer clic en el botón POST. Compartiendo debajo de la captura de pantalla de la salida mostrada.
PUT Solicitud HTTP
Editemos el precio del robot que tiene un valor de pk 2. Puede navegar por la siguiente URL y desplazarse hacia abajo.
http://localhost:8000/robot/2/
Compartiendo la captura de pantalla del navegador. Puede cambiar el precio a 27000 y hacer clic en el botón PONER.
Compartiendo la captura de pantalla de la salida.
ELIMINAR solicitud HTTP
Puede crear una nueva entrada de prueba y explorar la URL con el valor pk.
http://localhost:8000/robot/2/
Puede notar un botón ELIMINAR. Compartiendo la captura de pantalla del navegador a continuación:
Al hacer clic en el botón Eliminar, el navegador confirma lo mismo. Puede hacer clic en el botón Eliminar en la ventana de confirmación. Compartiendo la captura de pantalla a continuación.
Si la eliminación es exitosa, muestra el siguiente resultado.
Vamos a terminar
A partir de esta sección, entendimos cómo hacer uso de la función de API navegable en el marco de la API REST de Django. Redactamos y enviamos requests HTTP que generan contenido de texto/html como respuesta y también analizamos la respuesta en un navegador web.
Publicación traducida automáticamente
Artículo escrito por SonuGeorge y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA