Django Rest Framework:如何为嵌套模型[ManyToMany Fields]添加Rest API端点?

时间:2016-04-29 07:57:30

标签: django rest django-rest-framework

我有两个模型PatientDocter

# models.py
class Docter(models.Model):
    ...

class Patient(models.Model):
    ...
    cared_by = models.ManyToManyField(Docter)

现在我已经和ModelViewSet一起处理模型User的基本CRUD操作。

#viewsets.py
class PatientViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows patients to be viewed or edited.
    """

    queryset = Patient.objects.all()
    serializer_class = PatientSerializer
    permission_classes = (permissions.IsAuthenticated,)

    def get_queryset(self):
        return Patient.objects.filter(cared_by__in = [self.request.user])

    # Automatically add to cared by when creating object
    def perform_create(self, serializer):
        serializer.save(cared_by = [self.request.user])

我可以使用/users/端点访问此视图。 现在,我想将此端点扩展为对cared_by模型上的Patient字段执行基本CRUD操作。

因此/users/2/docters成为另一个终点。

POST /users/2/docters/可以patientinstance.cared_by.add(docter)

GET /users/2/docters/可以返回patientinstance.cared_by.all()

DELETE /users/2/docters/5可以patientinstance.cared_by.remove(docter)

但是现在我能想到的唯一方法是将自定义@detail_routes添加到PatientViewSet。这看起来像一个非常糟糕的做法,我正在重复很多代码。

所以任何人都可以指导我如何以正确的方式做到这一点。

1 个答案:

答案 0 :(得分:1)

您要做的是使用嵌套资源。为此,存在一个名为drf-nested-routers的第三方模块,可帮助您实现所需目标。

在你的情况下,你会有类似的东西:

router = DefaultRouter()
router.register(r'users', PatientViewSet, basename='users')

doctors_router = routers.NestedSimpleRouter(router, r'users' lookup='user')
doctors_router.register(r'doctors', DoctorViewSet, base_name='doctors')

这将为您提供以下路线:

/users/
/users/{pk}/
/users/{user_pk}/doctors/
/users/{user_pk}/doctors/{doctor_pk}/

查看其文档以获取更多详细信息。