Django REST框架 - 更新视图方法从未调用

时间:2016-06-08 14:23:05

标签: python django rest django-rest-framework

我正在使用Django REST Framework设计API端点,并希望它在以下端点接受GET,PATCH和PUT方法:

/department/<department_pk>/details/population/

Department模型和DepartmentPopulationDetail模型之间存在1:1的关系(DepartmentPopulationDetail模型有一个名为departmnet的FK)。 GET方法应该返回DepartmentPopulationDetail模型实例,PUT和PATCH应该允许一个人编辑同一个实例(不需要提供DepartmentPopulationDetail PK)。

我设法让端点为GET返回所需的响应,不允许DELETE或CREATE,但不能让它接受PUT或PATCH请求 - 实际上,update方法永远不会调用。如何让我的视图接受PUT和PATCH请求并编辑相应的模型?

urls.py
...
url(r'^departments/(?P<department_pk>[0-9]+)/details/population',
        include(department_urls.department_study_population_router.urls,
        namespace='department_study_population')),
...


serializers.py

class DepartmentStudyPopulationSerializer(serializers.ModelSerializer):

    class Meta:
        model = DepartmentStudyPopulation
        fields = ('pk', 'department', 'age', 'zip_code')
        read_only_fields = ('pk', 'department')

views.py
class DepartmentStudyPopulationViewSet(viewsets.ModelViewSet):
    queryset = DepartmentStudyPopulation.objects.all()
    serializer_class = DepartmentStudyPopulationSerializer
    http_method_names = ['get', 'put', 'patch']

    def update(self, request, department_pk, **kwargs):
        queryset = departmentStudyPopulation.objects.all()
        study_population = get_object_or_404(queryset, department_pk=department_pk)
        serializer = DepartmentStudyPopulationSerializer(
            study_population, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

2 个答案:

答案 0 :(得分:3)

为什么永远不会调用update()方法

这是因为您错误地定义了网址。

此网址

'departments/(?P<department_pk>[0-9]+)/details/population'

使用路由器生成以下网址。

'departments/(?P<department_pk>[0-9]+)/details/population/' # handle list views
'departments/(?P<department_pk>[0-9]+)/details/population/<pk>/' # handle detail views

因此,只有在以下网址上有请求update()代表pk id对象的DepartmentStudyPopulation时才会调用'departments/(?P<department_pk>[0-9]+)/details/population/<pk>/'方法。

update

如何处理所需网址上的retrieveupdate请求呢?

您需要进行一些更改,以便在以下所需的网址端点处理retrieve/department/<department_pk>/details/population/ 个请求。

ModelViewSet

首先,您应该使用RetrieveUpdateAPIView而不是detail,因为您只需要处理GET路由。此通用视图仅允许PUTPATCHdepartment_pk方法。

其次,您通过过滤department_pk字段而不是pk对象的DepartmentStudyPopulation字段来使用lookup_field url kwarg获取对象实例。您应该在视图中指定lookup_url_kwargdepartment_pk,其值为class DepartmentStudyPopulationDetailView(generics.RetrieveUpdateAPIView): queryset = DepartmentStudyPopulation.objects.all() serializer_class = DepartmentStudyPopulationSerializer lookup_field = 'department_pk' lookup_url_kwarg = 'department_pk' ,DRF将处理实例检索。

最终代码:

<强> views.py

url(r'^departments/(?P<department_pk>[0-9]+)/details/population', DepartmentStudyPopulationDetailView.as_view())

<强> urls.py

.dialog()

答案 1 :(得分:0)

您需要一个不同的URL来处理这些情况。

创建意味着您的DepartmentStudyPopulation是新的,并且没有主键(它在createion上生成)。

更新将需要一个包含主键的URL,以便Django知道要更新的对象。

(显示网址的文件对这个问题会有所帮助,因为我们不知道他们在哪里路由)。