如何使用Django Rest Framework修补单个字段?

pnh*_*gde 39 python api django django-rest-framework http-patch

我有一个包含许多字段的模型'MyModel',我想使用PATCH方法更新字段'status'.我正在使用基于类的视图.有没有办法实现PATCH?

Kev*_*own 40

序列化程序通过指定partial=True初始化序列化程序时允许部分更新.这是通用视图中默认PATCH处理请求的方式.

serializer = CommentSerializer(comment, data=request.data, partial=True)
Run Code Online (Sandbox Code Playgroud)

这将允许您更新序列化程序中的各个字段,或者根据需要更新所有字段,而不受标准PUT请求的任何限制.

  • 这到底在哪里? (25认同)
  • 好问题@ScottSmith.似乎文档和其他来源只引用这个单行作为进行部分更新的解决方案.但如果他不知道将这行代码放在何处,那就没有好处. (7认同)
  • 你需要在凯文提到的视图中覆盖`def update(self,request,*args,**kwargs)`或`def partial_update(self,request,*args,**kwargs)`.当您使用ModelSerializer或Serializer时,补丁不能按预期开箱即用,是因为在`BaseSerializer`构造函数中,有:`self.partial = kwargs.pop('partial',False)`这意味着即使你重写!!`partial_update` !! 你仍然需要在创建序列化程序时传递`partial = True`.因此,丢弃上面链接的通用视图的默认行为. (4认同)
  • 所以,我使用的是“ModelSerializer”和“RetrieveUpdateDestroyAPIView”。我对在哪里指定这个 `partial=True` 感到困惑! (2认同)

Uri*_*lit 14

正如Kevin Brown所说,你可以使用the partial=True,chefarov很好地澄清了.

我只想更正它们并说你可以自由使用泛型,具体取决于你使用的HTTP方法:

  • 如果您正在使用像ask一样的PATCH HTTP方法,那么您可以开箱即用.您可以看到以下UpdateModelMixin代码partial_update:

    def partial_update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return self.update(request, *args, **kwargs)
    
    Run Code Online (Sandbox Code Playgroud)
  • 对于与PATCH不同的任何HTTP方法,可以通过重写get_serializer方法来完成,如下所示:

    def get_serializer(self, *args, **kwargs):
        kwargs['partial'] = True
        return super(YOUR_CLASS, self).get_serializer(*args, **kwargs)
    
    Run Code Online (Sandbox Code Playgroud)

这将创建序列化程序为部分,其余的泛型将像魅力一样工作,而无需在update/partial_update机制中进行任何手动干预.

在引擎盖下

我使用了泛型:generics.UpdateAPIView它使用了UpdateModelMixin具有以下代码的:

def update(self, request, *args, **kwargs):
    partial = kwargs.pop('partial', False)
    instance = self.get_object()
    serializer = self.get_serializer(instance, data=request.data, partial=partial)
    …
Run Code Online (Sandbox Code Playgroud)

因此,如果重写该get_serializer函数,您实际上可以覆盖部分参数并强制它为true.

请注意,如果您希望它仅部分用于某些HTTP方法,则会使此方法更加困难.

我正在使用djangorestframework == 3.5.3


Chr*_*ris 5

它似乎支持开箱即用.在浏览器API上,导航到模型详细信息页面,在HTML Form选项卡单击旁边的底部Raw data,删除除ID字段和要更改的字段之外的JSON字符串中的所有内容,然后单击PATCH.PATCH执行部分更新.

我正在使用djangorestframework==3.2.4,并且不必对我的ViewSets和Serializers做任何事情来启用它.

在这个例子中,我们正在更新status_field模型的bool 字段,我正在使用jquery 2.2.1.将以下内容添加到<head>:

<script src="{% static 'my_app/jquery.min.js' %}"></script>
<script>
$(document).ready(function(){
    var chk_status_field = $('#status_field');
    chk_status_field.click(function(){
        $.ajax({url: "{% url 'model-detail' your_rendering_context.id %}",
            type: 'PATCH', timeout: 3000, data: { status_field: this.checked }
        })
        .fail(function(){
            alert('Error updating this model instance.');
            chk_status_field.prop('checked', !chk_status_field.prop('checked'));
        });
    });
});
</script>
Run Code Online (Sandbox Code Playgroud)

然后在<form>:

<input type="checkbox" id="status_field" {% if your_rendering_context.status_field %} 
    checked {% endif %} >
Run Code Online (Sandbox Code Playgroud)

我选择允许复选框更改,然后在发生故障时将其还原.但是你可以替换click使用mousedown,一旦AJAX调用成功只更新复选框值.我认为这会导致人们反复单击复选框以进行慢速连接.


fir*_*ast 5

如果有人仍然打算在ModelSerializer不更改您的大部分视图的情况下找到一个简单的解决方案,您可以ModelSerializerModelSerializers子类化并让您的所有s 都从中继承。

class PatchModelSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        kwargs['partial'] = True
        super(PatchModelSerializer, self).__init__(*args, **kwargs)

class ArticleSerializer(PatchModelSerializer):
    class Meta:
        model = Article
Run Code Online (Sandbox Code Playgroud)