在 Django REST framework 善用 SerializerMethodField 来优化不必要的查询

在 Django REST framework 善用 SerializerMethodField 来优化不必要的查询

首先来看一个例子,在一般情况下,对于有父子关系的对象,我们使用下面的方法来创建类。

一个Article类,一个Article对象可以有多个Comment实例,那么Django中类的定义如下:

#coding:utf-8
from django.db import models
from django.contrib.auth.models import User

class Article(models.Model):
    title = models.CharField(‘文章标题‘, max_length=1024, blank=False)
    summary = models.TextField(‘文章简介‘, blank=False)
    content = models.TextField(‘文章内容‘, blank=True, null=True)
    create_user = models.ForeignKey(User, related_name=‘article_create_user‘, verbose_name=‘创建用户‘)
    create_time = models.DateTimeField(‘创建时间‘, auto_now_add=True)

    def __str__(self):
        return self.title

    def __unicode__(self):
        return self.title

    class Meta:
        ordering = (‘-create_time‘,)

class Comment(models.Model):
    article = models.ForeignKey(Article, related_name=‘article_comments‘, verbose_name=‘文章‘)
    comment = models.CharField(‘评论‘, max_length=1024, blank=False)
    create_user = models.ForeignKey(User, related_name=‘article_comments_create_user‘, verbose_name=‘创建用户‘)
    create_time =models.DateTimeField(‘创建时间‘, auto_now_add=True)

    def __str__(self):
        return self.comment

    def __unicode__(self):
        return self.comment

    class Meta:
        ordering = (‘-create_time‘,)

根据上面类的定义,那么在 Django REST framework 我们通常按下面的方式定义 Serializer 类。

在 ArticleSerializer 类中增加一个属性 article_comments 来保存当前 Article 对象所有的评论集合。但是此时有个问题如果此 Article 对象所拥有的 Comment 比较多,此时就会影响性能。比如:

#coding:utf-8
from rest_framework import serializers
from .models import Article, Comment

class ArticleSerializer(serializers.ModelSerializer):
    article_comments = serializers.PrimaryKeyRelatedField(many=True, required=False, read_only=True)

    class Meta:
        model = Article
        fields = (‘id‘, ‘title‘, ‘summary‘, ‘content‘, ‘create_user‘, ‘create_time‘, ‘article_comments‘)

class CommentSerializer(serializers.ModelSerializer):

    class Meta:
        model = Comment
        fields = (‘id‘, ‘article‘, ‘comment‘, ‘create_user‘, ‘create_time‘)

其实在很多时候我们并不需要在查询 Article 对象的时候查询所拥有的 Comment 对象,很多时候我们只是需要一个 Article 所拥有 Comment 对象的总数就可以了,如果有需要再去查询 Comment 列表详细。此时我们就可以使用 Django REST framework 提供的 SerializerMethodField 来实现这个目的。如下:

#coding:utf-8
from rest_framework import serializers
from .models import Article, Comment

class ArticleSerializer(serializers.ModelSerializer):
    article_comments_count = serializers.SerializerMethodField()

    class Meta:
        model = Article
        fields = (‘id‘, ‘title‘, ‘summary‘, ‘content‘, ‘create_user‘, ‘create_time‘, ‘article_comments_count‘)

    def get_article_comments_count(self, obj):
        return obj.article_comments.all().count()

class CommentSerializer(serializers.ModelSerializer):

    class Meta:
        model = Comment
        fields = (‘id‘, ‘article‘, ‘comment‘, ‘create_user_id‘, ‘create_user_name‘, ‘create_time‘)
  • 首先在 ArticleSerializer 中去除 article_comments 属性;
  • 然后在 ArticleSerializer 中增加一个属性 article_comments_count,并把这个属性添加到 Meta 的 fields 列表里;
  • 添加一个 get_article_comments_count 方法,这个方法的命名规则就是在上面声明的属性前面加上个 “get_” 前缀,并接受一个 obj 参数,这个 obj 参数就是当前的 Article 对象实例。

此时在查看 Article 的api中就只显示 Comment 的总数而不显示具体列表了。

时间: 2024-08-13 08:11:22

在 Django REST framework 善用 SerializerMethodField 来优化不必要的查询的相关文章

DRF(Django REST Framework)框架

目录 一.DRF中的Request 二.前戏: 关于面向对象的继承 三.初级版本 1. settings.py文件 -- 注册app 2. models.py文件 -- 创建表 3. admin.py文件 4. 根目录下urls.py -- 路由匹配 5. bms/views.py -- 视图函数 6. bms/modelserializers.py -- 自定义序列化工具 四.进化版: 使用自定义混合类和自定义通用类 五.超级进化版: 使用GenericViewSet通用类 六.究极进化版:

Django Rest framework序列化流程

目录 一 什么是序列化 二 Django REST framework配置流程之Serializer 三 Django REST framework配置流程之ModelSerializer 一 什么是序列化 序列化模型与序列化关系模型 序列化模型,顾名思义,即对 models 里的数据模型作序列化. 而序列化关系模型则是对 models 里数据模型中带有关系的如 ForeignKey, ManyToManyField 和 OneToOneField 字段作序列化. Django Rest Fra

Django Rest Framework --- 序列化组件

一.序列化组件的作用 在前后端分离开发时,前端与后端用来交互的数据的格式是一致的(数据格式为字符串的json数据),于是后端程序员在传递数据时,便要将数据封装成符合格式的数据,如果不借助方法,手动进行数据封装,会非常的浪费时间,在Django rest framework中的序列化组件帮我们解决了这个问题. 二.Django自带的序列化组件 from django.core import serializers def test(request): book_list = Book.object

Django REST framework序列化

Django REST framework序列化 开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列化和反序列化为诸如json之类的表示形式的方式 models部分 from django.db import models class Book(models.Model): title = models.CharField(max_length=32) price = models.IntegerField() pub_date = models.DateFie

Django Rest Framework Serializer的简单使用

1.RESTful 1.1 定义 REST(Representational State Transfer)与技术无关,代表一种软件架构风格,中文为表征状态转移. 1.2 RESTful API设计 API与用户的通信协议,总是使用HTTPS协议 域名 https://api.example.com 尽量将API部署在专用域名(会存在跨域问题) https://example.org/api/ API在路径上,简单 版本 URL 如:https://api.example.com/v1/ 代表v

利用 Django REST framework 编写 RESTful API

利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framework 真乃一大神器,可以轻易的甚至自动化的搞定很多事情,比如: 自动生成符合 RESTful 规范的 API 支持 OPTION.HEAD.POST.GET.PATCH.PUT.DELETE 根据 Content-Type 来动态的返回数据类型(如 text.json) 生成 browserable

django rest framework 入门

django rest framework 入门1-序列化 Serialization 分类: Python 2013-01-22 22:24 11528人阅读 评论(0) 收藏 举报 djangopythonrest framework ************************************ 广告时间: 海淘导航网站推荐:海淘库:http://www.haitaocool.com/ 需要的请收藏哦 ************************************ 1.

Django rest framework 使用自定义认证方式

Django rest framework 使用自定义认证方式 Django使用自定义认证方式 介绍了 "Django使用自定义认证方式",这一篇说说怎样在前一篇的基础上提供rest api. 修改settings.py中INSTALLED_APPS,添加 'login' app. 给login app增加serializers.py文件 #coding:utf-8 from django.contrib.auth.models import User from rest_framew

Django REST framework 的TokenAuth认证及外键Serializer基本实现

一,Models.py中,ForeignKey记得要有related_name属性,已实现关联对象反向引用. app_name = models.ForeignKey("cmdb.App",related_name='deploy_app', verbose_name="App") 二,Settings.py文件中,加入对Django REST framework的基本设置. REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSE