从Url参数

时间:2017-06-14 04:31:32

标签: python django url kwargs django-rest-viewsets

嗨我有一个类似的模型:

class Appointment(models.Model):
    hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE)
    patient = models.ForeignKey(Patient, on_delete=models.CASCADE)

我的观点如下:

class AppointmentViewSet(viewsets.ModelViewSet):
    queryset = Appointment.objects.all()
    serializer_class = AppointmentSerializer

在我的网址中:

router.register(r'appointments', AppointmentViewSet)

现在我想通过一些患者ID过滤约会列表。这个id应该由请求者通过url给出。我正在考虑使用 kwargs 来捕获它。但我不知道该怎么做。我知道我必须覆盖列表方法。

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? 

如何自定义网址和/或视图以容纳患者ID参数?我只想修改列表请求,所有其他操作(创建,细节,销毁)应该由modelviewset的默认行为来处理。

感谢。

3 个答案:

答案 0 :(得分:2)

您可以定义一个自定义方法来处理患者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)

list_route装饰器将您的方法标记为需要路由。

<强>更新

您可以手动将网址注册为:

url(r'^(?P<id>[0-9]+)/appointments/$', AppointmentViewSet.as_view({'get': 'patient_appointments'}), name='patient-appointments')

答案 1 :(得分:2)

以下是我最终如何做到这一点:

我添加了一个这样的网址条目:

url(r'appointments/ofpatient/(?P<patient>\d+)', AppointmentViewSet.as_view({'get': 'list'})),

我可以在浏览器中调用:

http://localhost:8000/appointments/ofpatient/6

并在视野中:

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)

这样,/约会网址也会被保留。

答案 2 :(得分:1)

尝试

if(self.request.get('pid')):
    pk = self.request.get('pid')
    all_appointment = Appointment.objects.filter(patient__pk=pk)

对于患者网址将为appoinment/?pid=9

以及约会详情appoinment/9