Hi I have a model like:
class Appointment(models.Model):
hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE)
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
My View looks like:
class AppointmentViewSet(viewsets.ModelViewSet):
queryset = Appointment.objects.all()
serializer_class = AppointmentSerializer
In my urls:
router.register(r'appointments', AppointmentViewSet)
Now I want to filter the list of appointments by some patient id. This id should be given by the requester through url. I'm thinking about using kwargs to catch it. But I have no idea how to do it. I know I have to override the list method.
def list(self, request, *args, **kwargs):
# what do I write here? so that the queryset would be filtered by patient id sent through the url?
How do I customize the url and/or the view to accommodate the patient id parameter? I just want to modify the list request, all other actions(create, details, destroy) should be handled by the modelviewset's default behavior.
Thanks.
Here is how I ended up doing it:
I've added an url entry like this:
url(r'appointments/ofpatient/(?P<patient>\d+)', AppointmentViewSet.as_view({'get': 'list'})),
Which I can call from the browser as:
http://localhost:8000/appointments/ofpatient/6
and in view:
def list(self, request, patient=None):
if patient:
patient = Patient.active.filter(id=patient)
appts = Appointment.active.order_by('appt_time').filter(patient=patient)
serializer = self.get_serializer(appts, many=True)
return Response(serializer.data)
else:
appts = Appointment.active.order_by('appt_time')
serializer = self.get_serializer(appts, many=True)
return Response(serializer.data)
In this way, the /appointments url is also preserved.
You can define a custom method to handle the routing for the url with the patient id:
from rest_framework.decorators import list_route
rom rest_framework.response import Response
class AppointmentViewSet(viewsets.ModelViewSet):
...
@list_route()
def patient_appointments(self, request, id=None):
serializer = self.get_serializer(queryset.filter(patient_id=id), many=True)
return Response(serializer.data)
The list_route
decorator marks your method as requiring routing.
Update:
You can manually register the url as:
url(r'^(?P<id>[0-9]+)/appointments/$', AppointmentViewSet.as_view({'get': 'patient_appointments'}), name='patient-appointments')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With