我正在try 用Django Rest Framework来实现partial_update,但是我需要一些澄清,因为我被卡住了.

  1. Why do we need to specify partial=True?

  2. What is inside of serialized variable?

  3. How would one finish the implementation here?

视图集

class DemoViewSet(viewsets.ModelViewSet):
    serializer_class = Demo序列化程序

    def partial_update(self, request, pk=None):
        serialized = Demo序列化程序(request.user, data=request.data, partial=True)
        return Response(status=status.HTTP_202_ACCEPTED)

序列化程序

class Demo序列化程序(serializers.Model序列化程序):
    class Meta:
        model = Demo
        fields = '__all__'

    def update(self, instance, validated_data):
        print 'this - here'
        demo = Demo.objects.get(pk=instance.id)
        Demo.objects.filter(pk=instance.id)\
                           .update(**validated_data)
        return demo

推荐答案

我之前和你也有同样的问题,但是当我挖洞进入睡觉_框架的源代码时,我得到了以下发现,希望能有所帮助:

对于问题1,为什么需要指定PARTIAL=TRUE?

这个问题与HTTP verbs有关.

100:PUT方法将目标资源的所有当前表示形式替换为请求有效负载.

100:Patch方法用于对资源进行部分修改.

一般来说,partial用于判断客户端向视图提交数据时是否需要模型中的字段进行字段验证.

例如,我们有一个这样的Book型号,请注意nameauthor_name字段都是mandatory(不为空&;不为空).

class Book(models.Model):
    name = models.CharField('name of the book', max_length=100)
    author_name = models.CharField('the name of the author', max_length=50)

# Create a new instance for testing
Book.objects.create(name='Python in a nut shell', author_name='Alex Martelli')

对于某些场景,我们可能只需要更新模型中的部分字段,例如,我们只需要更新Book中的name字段.因此,对于这种情况,客户机将只向视图提交具有新值的name字段.客户提交的数据可能如下所示:

{"pk": 1, name: "PYTHON IN A NUT SHELL"}

但是您可能已经注意到,我们的模型定义不允许author_name为空.所以我们必须用101代替102.因此,睡觉框架将不会对请求数据中缺失的字段执行field validation check.

出于测试目的,您可以为updatepartial_update创建两个视图,您将更好地理解我刚才所说的内容.

示例:

views.py
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import UpdateModelMixin
from rest_framework.viewsets import ModelViewSet
from rest_framework import serializers


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book


class BookUpdateView(GenericAPIView, UpdateModelMixin):
    '''
    Book update API, need to submit both `name` and `author_name` fields
    At the same time, or django will prevent to do update for field missing
    '''
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

class BookPartialUpdateView(GenericAPIView, UpdateModelMixin):
    '''
    You just need to provide the field which is to be modified.
    '''
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def put(self, request, *args, **kwargs):
        return self.partial_update(request, *args, **kwargs)
urls.py
urlpatterns = patterns('',
    url(r'^book/update/(?P<pk>\d+)/$', BookUpdateView.as_view(), name='book_update'),
    url(r'^book/update-partial/(?P<pk>\d+)/$', BookPartialUpdateView.as_view(), name='book_partial_update'),
)

Data to submit

{"pk": 1, name: "PYTHON IN A NUT SHELL"}

当您向/book/update/1/提交上述json时,您将得到以下错误,HTTP_STATUS_CODE=400:

{
  "author_name": [
    "This field is required."
  ]
}

但是当你将上面的json提交给/book/update-partial/1/时,你会得到HTTP_STATUS_CODE=200,并有以下响应:,

{
  "id": 1,
  "name": "PYTHON IN A NUT SHELL",
  "author_name": "Alex Martelli"
}

关于问题2.序列化变量的内部是什么?

serialized是将模型实例包装为可序列化对象的对象.您可以使用序列化后的代码生成一个包含serialized.data的纯JSON字符串.

关于问题3.如何在这里完成实现?

我想当你读完上面的答案时,你可以自己回答,你应该知道什么时候用update,什么时候用partial_update.

如果你还有什么问题,尽管问.我刚刚看了睡觉框架的部分源代码,可能有些术语理解得不是很深入,有错误的地方请指正……

Django相关问答推荐

Django Prefetch上的多重过滤

Django 相当于子查询

Django 注释(),计数()

基于令牌的身份验证如何工作?

NoneType对象没有属性保存Django

Django 嵌套事务 - with transaction.atomic()

使用 Python/Django 上传大文件

关于Django中批量保存对象的问题

在 GoDaddy 上安装 django 站点

在 Django 中,您可以向查询集添加方法吗?

Django 管理命令参数

Django App 配置不当 - 应用程序模块有多个文件系统位置

Django populate() 不可重入

在 django 模板中遇到 user.is_authenticated 问题

Django 登录到控制台

更新Django模型对象多个字段的有效方法

Python/Django:从 values_list() 创建一个更简单的列表

django 管理列表中的外键显示

django 应用基于条件的样式类

Django admin:使字段在添加中可编辑但不可编辑