我正在使用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)
答案 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
如何处理所需网址上的retrieve
和update
请求呢?
您需要进行一些更改,以便在以下所需的网址端点处理retrieve
和/department/<department_pk>/details/population/
个请求。
ModelViewSet
首先,您应该使用RetrieveUpdateAPIView
而不是detail
,因为您只需要处理GET
路由。此通用视图仅允许PUT
,PATCH
和department_pk
方法。
其次,您通过过滤department_pk
字段而不是pk
对象的DepartmentStudyPopulation
字段来使用lookup_field
url kwarg获取对象实例。您应该在视图中指定lookup_url_kwarg
和department_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知道要更新的对象。
(显示网址的文件对这个问题会有所帮助,因为我们不知道他们在哪里路由)。