No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Refactorizando vistas en Django REST Framework con vistas genéricas

11/21
Recursos

Hemos visto cómo utilizar vistas genéricas en Django para crear vistas de detalle, simplificando el código y evitando la duplicación. A través de la clase RetrieveUpdateDestroyAPIView, podemos obtener, modificar o eliminar recursos de manera eficiente, reduciendo la cantidad de código a manejar.

¿Cómo evitar la duplicación de código con vistas genéricas?

  • Django permite usar vistas genéricas como RetrieveAPIView, UpdateAPIView y DestroyAPIView.
  • Sin embargo, es más eficiente usar la clase combinada RetrieveUpdateDestroyAPIView, que integra estas tres funcionalidades.
  • Con esta clase podemos obtener, actualizar o eliminar un recurso sin necesidad de importar múltiples vistas.

¿Cómo funciona el refactor a las vistas genéricas?

  • El código que antes obtenía el objeto y devolvía un error 404 si no se encontraba, ahora es reemplazado por una vista genérica que maneja esa lógica automáticamente.
  • Al definir la vista genérica RetrieveUpdateDestroyAPIView, simplemente necesitamos definir las variables correspondientes, como el modelo y los permisos, y se manejan todas las operaciones CRUD (create, read, update, delete).
  • Esto nos permite reducir significativamente el código y mantener la funcionalidad.

¿Cómo realizar validaciones con las vistas genéricas?

  • Django continúa manejando validaciones, como las que se generan al enviar datos incorrectos, por ejemplo, una fecha inválida.
  • Estas validaciones son útiles en formularios de frontend, ya que permiten mostrar al usuario por qué una solicitud ha fallado.

¿Qué sigue después de implementar vistas genéricas?

  • El siguiente paso es usar view sets, que nos permitirán agrupar las vistas de una manera más eficiente y evitar la repetición de código.
  • Aunque se ha logrado simplificar el código con las vistas genéricas, los view sets llevarán esta simplificación un paso más allá, agrupando operaciones similares en un solo conjunto.

Aportes 7

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Estoy sorprendido de tanto refactor jajaja Me encanta esto de Django REST Framework
Sinceramente muy impresionado con la simplificación que tiene django :)
Como tip: cuando empezamos a usar vistas genericas ya no es necesario declarar los metodos: *\["GET", "PUT", "DELETE"])* vienen implicitos.
Hermoso código: ```python from .serializers import PatientSerializer from .models import Patient from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework import status from rest_framework.views import APIView from rest_framework.generics import ( ListAPIView, CreateAPIView, RetrieveUpdateDestroyAPIView, ) # GET /api/patients => Listar # POST /api/patients => Crear # GET /api/patients/<pk>/ => Detalle # PUT /api/patients/<pk>/ => Modificación # DELETE /api/patients/<pk>/ => Borrar class ListPatientsView(ListAPIView, CreateAPIView): allowed_methods = ['GET', 'POST'] serializer_class = PatientSerializer queryset = Patient.objects.all() class DetailPatientView(RetrieveUpdateDestroyAPIView): allowed_methods = ['GET', 'PUT', 'DELETE'] serializer_class = PatientSerializer queryset = Patient.objects.all() ```
Si por alguna razon les nace ocupar la palabra id en la url en lugar de pk que tenes que saber que se puede. el profe por defecto ocupa pk como convencion de Django, pero se puede cambiar asi ```python urlpatterns = [ path('', ListPatientsView.as_view()), path('<int:id>/', DetailPatientView.as_view()), ] ``` ```python class DetailPatientView(RetrieveUpdateDestroyAPIView): allowed_methods = ['GET','PUT','DELETE'] lookup_field = "id" serializer_class = PatientSerializer queryset = Patient.objects.all() ```
Ventajas de utilizar vistas genéricas en Django Rest Framework: 1. **Reducción de código repetitivo**: Implementaciones predefinidas para operaciones comunes. 2. **Mejora de consistencia y mantenibilidad**: Aplicación de patrones uniformes en toda la API. 3. **Aceleración del desarrollo**: Permite centrarse en la lógica específica de la aplicación. 4. **Facilidad de integración y extensión**: Composición de comportamientos reutilizables. 5. **Promoción de buenas prácticas**: Adherencia a los principios de diseño de Django y REST.
```python from rest_framework import viewsets from rest_framework.response import Response from rest_framework import status from .models import Cliente, Reserva, Historial from .serializers import ClienteSerializer, ReservaSerializer, HistorialSerializer class ClienteViewSet(viewsets.ModelViewSet): queryset = Cliente.objects.all() serializer_class = ClienteSerializer def retrieve(self, request, pk=None): """ Sobrescribe el método retrieve para personalizar la respuesta al obtener un cliente por su pk. """ try: cliente = Cliente.objects.get(pk=pk) serializer = ClienteSerializer(cliente) return Response(serializer.data, status=status.HTTP_200_OK) except Cliente.DoesNotExist: return Response({"error": "Cliente no encontrado"}, status=status.HTTP_404_NOT_FOUND) class ReservaViewSet(viewsets.ModelViewSet): queryset = Reserva.objects.all() serializer_class = ReservaSerializer class HistorialViewSet(viewsets.ModelViewSet): queryset = Historial.objects.all() serializer_class = HistorialSerializer ```from rest\_framework import viewsetsfrom rest\_framework.response import Responsefrom rest\_framework import statusfrom .models import Cliente, Reserva, Historialfrom .serializers import ClienteSerializer, ReservaSerializer, HistorialSerializer class ClienteViewSet(viewsets.ModelViewSet):    queryset = Cliente.objects.all()    serializer\_class = ClienteSerializer     def retrieve(self, request, pk=None):        """        Sobrescribe el método retrieve para personalizar la respuesta al obtener un cliente por su pk.        """        try:            cliente = Cliente.objects.get(pk=pk)            serializer = ClienteSerializer(cliente)            return Response(serializer.data, status=status.HTTP\_200\_OK)        except Cliente.DoesNotExist:            return Response({"error": "Cliente no encontrado"}, status=status.HTTP\_404\_NOT\_FOUND) class ReservaViewSet(viewsets.ModelViewSet):    queryset = Reserva.objects.all()    serializer\_class = ReservaSerializer class HistorialViewSet(viewsets.ModelViewSet):    queryset = Historial.objects.all()    serializer\_class = HistorialSerializer