Django 如何更新单行上的单个列?
我正试图为我的Django REST应用程序编写一个简单的更新视图,但我不知道怎么做。我得到了从403到500的误差范围 基本上,我有一个表'Foo',我想将'active'字段从'True'设置为'False'。以下是我目前的观点:Django 如何更新单行上的单个列?,django,django-rest-framework,Django,Django Rest Framework,我正试图为我的Django REST应用程序编写一个简单的更新视图,但我不知道怎么做。我得到了从403到500的误差范围 基本上,我有一个表'Foo',我想将'active'字段从'True'设置为'False'。以下是我目前的观点: class DisableFoo(generics.UpdateAPIView): permission_classes = (permissions.IsAuthenticated,) serializer_class = FooSerializ
class DisableFoo(generics.UpdateAPIView):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = FooSerializer
queryset = Foo.objects.all()
def perform_update(self, serializer):
queryset = Foo.objects.filter(pk = self.request.data['id'])
queryset.update(active = False)
但是,这会导致断言错误:
Expected view DisableFoo to be called with a URL keyword argument named "pk".
Fix your URL conf, or set the '.lookup_field' attribute on the view correctly.
您不应发送要使用request.data更新的行的
id
,而应在url
中发送
因此,如果你现在正在击球,比如:
/api/foo/
试一试
/api/foo/
当然,这还不够。你还应该考虑更多的事情。
您正在挂接perform\u update
方法。但这不太可能是正确的<调用code>perform\u update是为了用serializer.save()
更新整个对象,因此只有当serializer.is\u valid()
时才会调用它
这意味着您必须发送有效的Foo
对象。但那不是你想要的。您只需要更新Foo
对象的单个字段。因此,正确的方法是使用partial\u update
<当您请求/api/foo/
因此,如果您在请求中向/api/foo/
发送补丁
请求,且active=0
,则数据DRF将自动更新对象,而无需任何进一步的代码更改。只是使用
class DisableFoo(generics.UpdateAPIView):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = FooSerializer
queryset = Foo.objects.all()
但这最终将公开所有要更新的模型字段。因此,您可以覆盖partial\u update
方法,如下所示:
def partial_update(self, request, *args, **kwargs):
instance = self.get_object()
instance.active = False
instance.save(update_fields=['active'])
return Response()
另一种方法
DRF支持创建via@detail\u route
和@list\u route
装饰器
您可以使用@detail_route
创建自定义禁用操作。考虑下面的代码和平:
class FooViewSet(viewsets.GenericViewSet):
queryset = Foo.objects.all()
serializer_class = FooSerializer
@detail_route(methods=['post'])
def disable(self, request, pk=None):
instance = self.get_object()
instance.active = False
instance.save(update_fields=['active'])
return Response('done')
向/api/foo//disable
发出POST
请求将调用我们刚刚编写的disable
方法,并禁用
下的foo
实例
通过这种方式,您可以避免使用
PATCH
request方法的要求。我更改了它,但现在得到了HTTP 400错误请求作为答复。我用一些解释更新了答案,但您还应该通过查看错误日志来了解如何调试此类错误。谢谢,我将在一分钟内尝试更改。同时,如果请求总是将值设置为False,我是否必须在请求中设置active=0
?这不是多余的吗?另外,我的HTTP客户端不支持补丁方法。如果不覆盖partial\u update
,则必须在请求中发送它。这基本上告诉序列化程序使用什么值更新哪个字段。因此,如果您还发送active=0&some\u other\u field=some\u other\u value
,它们都将得到更新。关于不受支持的补丁
方法,请检查我的更新答案。