Agendar citas en una API médica requiere precisión. Aquí verás cómo construir un endpoint anidado en Django Rest para crear y listar appointments desde el viewset de doctores, aplicando validación con serializer, filtros con el ORM y respuestas HTTP claras. La solución es segura, reusable y alineada con REST.
¿Cómo estructurar el endpoint anidado para appointments?
Un endpoint anidado aprovecha el recurso padre. En este caso, se cuelga de Doctors: el camino queda como /doctors/{id}/appointments/. Para lograrlo, se define una @action en el viewset del doctor con detail=True y métodos get y post. Además, se especifica serializer_class para mostrar los campos correctos en la interfaz navegable de Django Rest.
detail=True limita la acción al recurso doctor actual.
serializer_class evita que se muestren campos del doctor cuando se crea un appointment.
get debe listar appointments del doctor. post debe crearlos.
from rest_framework.decorators import action
from rest_framework import status, viewsets
from rest_framework.response import Response
from bookings.serializers import AppointmentSerializer
from bookings.models import Appointment
classDoctorViewSet(viewsets.ModelViewSet):...@action(detail=True, methods=['get','post'], serializer_class=AppointmentSerializer)defappointments(self, request, pk=None): doctor = self.get_object()if request.method.lower()=='post': data ={**request.data,'doctor': doctor.id} serializer = AppointmentSerializer(data=data) serializer.is_valid(raise_exception=True) serializer.save()return Response(serializer.data, status=status.HTTP_201_CREATED) appointments = Appointment.objects.filter(doctor=doctor) serializer = AppointmentSerializer(appointments, many=True)return Response(serializer.data)
¿Cómo crear una cita con post usando serializer y validación?
El objetivo es que el usuario no pueda manipular el doctor. Por eso, se inyecta el id del doctor desde la URL con self.get_object() y se construye un diccionario data que combina los datos del usuario con el doctor.id. Luego se instancia el serializer con data, se valida y se guarda.
self.get_object() obtiene el doctor según el pk de la URL.
request.method dirige el flujo entre post y get.
serializer.is_valid(raise_exception=True) aplica reglas de validación y devuelve errores claros.
serializer.save() persiste el appointment porque es un ModelSerializer.
doctor = self.get_object()if request.method.lower()=='post': data ={**request.data,'doctor': doctor.id} serializer = AppointmentSerializer(data=data) serializer.is_valid(raise_exception=True) serializer.save()return Response(serializer.data, status=status.HTTP_201_CREATED)
Habilidades y conceptos en juego:
Seguridad por diseño: el doctor se toma de la URL, no del cuerpo del request.
Buenas prácticas REST: post crea, get lista.
Experiencia de desarrollo: el serializer_class en el decorador muestra el formulario correcto en la interfaz navegable.
Control de acceso: el endpoint requiere estar logueado.
¿Cómo listar las citas con get filtrando por doctor?
Para listar, se filtran los appointments por el doctor actual con el ORM de Django y se serializan con many=True. El estado por defecto es 200, por lo que no es necesario especificarlo.
Appointment.objects.filter(doctor=doctor) devuelve solo las citas del doctor.
many=True indica que se serializa una colección.
Response(serializer.data) retorna JSON listo para el cliente.
Keywords y datos importantes para fijar aprendizaje:
url del recurso: /doctors/{id}/appointments/.
acción anidada con @action(detail=True, methods=['get', 'post']).
uso de serializer_class=AppointmentSerializer en el decorador.
patrón de validación: is_valid(raise_exception=True).
creación con save() y confirmación HTTP_201_CREATED.
listado con many=True y ORM filtrando por doctor=doctor.
vista de detalle: la acción depende del doctor existente.
interfaz navegable: sin serializer_class se mostrarían campos del doctor por defecto.
control de sesión: acceso solo para usuarios autenticados.
acciones extra: ejemplo previo set_on_vacation en Doctors.
¿Tienes dudas o quieres extenderlo con borrar una cita en la misma acción? comenta cómo planeas manejar permisos y validaciones, y lo revisamos juntos.