我目前正在为我的应用程序RESTful API实现djangorest框架.在try 过它之后,我仍然不清楚.create(self, validated_data).update(self, validated_data)在序列化程序中用来做什么.据我所知,CRUD只调用viewsets.ModelViewSet中的4个主要方法:create()retrive()update()destroy().

我还try 过调试和打印内容,以查看在ModelViewSetModelSerializer中调用.create().update()方法的时间.显然,当我执行HTTP谓词时,只调用ModelViewSet中的方法.但是,对于ModelSerializer,我在这两个方法中没有看到任何调用.我只想知道ModelSerializer中使用的那些方法是什么,因为我看到人们在序列化程序中经常覆盖这些方法.

推荐答案

您确实必须在视图和序列化程序之间进行拆分.

Serializers

Serializer是一个独立的对象.它用于将Django模型(实际上是任何类型的python数据 struct )转换为序列化形式,反之亦然.

ModelSerializer子类是一种特殊的Serializer,它添加了"从模型加载"和"保存到模型"功能. "保存到模型"入口点是save()方法.为便于覆盖,其默认实现将其工作委托给序列化程序的create()update()方法,具体取决于它是创建新的模型实例还是更新模型实例.

它的目的是定制:它为开发人员提供了只覆盖create方法、update方法或常见行为的选项.

def save(self, **kwargs):
    # Will be done on every save
    kwargs['last_changed'] = timezone.now()
    return super().save(**kwargs)

def create(self, instance, data):
    # Will only be done if a new object is being created
    data['initial_creation'] = timezone.now()
    return super().create(instance, data)

这是一个基本的例子.在那里,每次保存对象(无论是创建还是更新)时都会设置last_changed字段.

Viewsets

在一个完全不同的地方,Django 睡觉框架提供了Viewsets个.这些是有组织的视图集合,围绕实现模型的CRUD API. 因此,它将其功能 struct 化为一组方法,即create()retrieve()/list()update()delete().

要点是:there is no connection whatsoever between the viewset's 100 method and the serializer's 100 method.

恰好视图集的方法的默认实现使用ModelSerializer,并且该序列化程序的save()方法的默认实现将作业(job)委托给同名的方法.

顺便说一句,关于last_changed个例子,下面是您在视图中的操作方式:

def perform_create(self, serializer):
    now = timezone.now()
    serializer.save(initial_creation=now, last_changed=now)

def perform_update(self, serializer):
    serializer.save(last_changed=timezone.now())

这在功能上与上面的示例相同,但存在于视图集中.

Conclusion

回到您的问题,您应该覆盖的具体内容取决于您要添加的任务由哪个对象负责.

  • 如果您的自定义行为是序列化过程的一部分,即将原始数据转换回适当的Django模型并将其保存的过程,那么您应该覆盖Serializer的方法.
  • 另一方面,如果您的自定义行为特定于您的视集,则应替代Viewset的方法.

作为提示,您可能会问自己以下问题:如果我在另一个地方(可能是另一个视图集)使用相同的序列化程序,它是否应该始终显示该行为?

Django相关问答推荐

如何在REST框架中以SON格式返回错误,而不是HTML格式返回错误?

如何在Django CMS中更新上下文

SQLite上可以正常使用Many2Many链接注释,但MariaDB上无法正常使用(生产环境)

使用OuterRef过滤器获取Django记录的最大值

如何使用 jQuery 建立 Django 网站

如何运行克隆的 Django 元素?

Django聚合:仅求和返回值?

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

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

是否可以将 FastAPI 与 Django 一起使用?

Django-获取外键模型

Django UrlResolver,在运行时添加 url 进行测试

ImportError:升级到 Django 4.0 后无法从 'django.conf.urls' 导入名称 'url'

如何查询名称包含python列表中任何单词的模型?

AssertionError: `HyperlinkedIdentityField` 需要序列化程序上下文中的请求

Django将HttpResponseRedirect返回到带有参数的url

get_or_create() 是否必须立即保存?

您如何在本地针对 OpenID 进行开发

警告:找不到分发的 svn 位置==0.6.16dev-r0

Django Debug Toolbar:了解时间面板( time panel)