Django 在一次调用中序列化多个对象

2024-04-22

我想知道如何减少序列化时对数据库的调用次数:

我有以下2个型号:

 class House(models.Model):
     name = models.CharField(max_length = 100, null = True, blank = True)
     address = models.CharField(max_length = 500, null = True, blank = True)

 class Room(models.Model):
      house = models.ForeignKey(House)
      name  = models.CharField(max_length = 100)

有1栋房子,可以有多个房间。

我正在使用 django-rest-framework 并尝试在内部将所有三件事序列化在一起。

 class HouseSerializer(serializers.ModelSerializer)
    rooms = serializers.SerializerMethodField('room_serializer')

    def room_serializer(self):
         rooms = Room.objects.filter(house_id = self.id) # we are in House serializer, so self is a house
         return RoomSerializer(rooms).data

    class Meta:
        model = House
        fields = ('id', 'name', 'address')

因此,现在,对于我想要序列化的每栋房屋,我需要为其房间进行单独的调用。它有效,但这是一个额外的调用。 (想象一下我试图将很多东西打包在一起!)

现在,如果我有 100 栋房屋,要序列化所有内容,我需要进行 100 次数据库命中,时间复杂度为 O(n)

我知道如果我能将所有信息集中在一起,我可以将点击次数减少到 2 次。 O(1) 时间

my_houses = Houses.objects.filter(name = "mine")
my_rooms = Rooms.objects.filter(house_id__in = [house.id for house in my_houses])

我的问题是我该怎么做?并让序列化者感到高兴?

我可以在完成两次调用后以某种方式进行循环,将一个房间“附加”到一个房屋上,然后将其序列化吗? (我可以添加这样的属性吗?)如果可以,我如何让我的序列化器读取它?

请注意,我不需要 django-rest-serializer 来允许我以这种方式更改房间中的属性。这仅适用于 GET。


正如目前所写,使用SerializerMethodField,您正在进行 N+1 次查询。我已经在 Stack Overflow 上多次介绍过这个问题优化数据库查询 https://stackoverflow.com/a/26598897/359284一般来说,这与您的方式类似提高 Django 的性能 https://docs.djangoproject.com/en/dev/topics/db/optimization/。您正在处理一对多关系,可以像多对多关系一样对其进行优化prefetch_related.

class HouseSerializer(serializers.ModelSerializer)
    rooms = RoomSerializer(read_only=True, source="room_set", many=True)

    class Meta:
        model = House
        fields = ('id', 'name', 'address', )

我所做的更改使用嵌套序列化器,而不是在SerializerMethodField。我已经将其限制为read_only,正如您提到的,您只需要它GET请求和可写序列化器在 Django REST Framework 2.4 中存在问题。

作为你的反向关系Room -> House关系没有设置,是默认的room_set。您可以(并且应该)通过设置来覆盖它related_name on the ForeignKey字段,并且您需要调整source因此。

为了防止 N+1 查询问题,您需要覆盖视图上的查询集。在通用视图的情况下,这将在queryset属性或在get_queryset方法就像queyset = House.objects.prefetch_related('room_set')。这将请求所有相关的房间以及House对象,因此您将只有两个请求,而不是 N+1 个请求。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django 在一次调用中序列化多个对象 的相关文章

随机推荐

  • Android MediaRecorder 和 setOutputFile

    我阅读了 Android SDK 发现 MediaRecorder 类可以从相机 音频或其他源获取输入并对其进行压缩 通过 setOutputFile 方法 您可以指定要存储数据的位置 文件或 URI 但是如果我想将该数据存储在内存缓冲区中
  • 将字符向量列表转换为数据帧

    我的输出 a 看起来像 str a List of 8883695 chr 1 3 20MICRONS A ACCRUALS chr 1 3 20MICRONS A ACCRUALS chr 1 3 20MICRONS A ACCRUALS
  • 检查针对 SQL Server 数据库的 LINQ 查询

    有什么方法可以在 NET 中查看我们正在触发的针对数据库的 LINQ 查询吗 例如 我正在 LINQ 中编写一个查询 我想看看触发了什么 SQL 查询来与数据库进行通信 有没有 Visual Studio 窗口或其他方式 你在寻找类似的东西
  • 带 python 列表的循环引用

    有人可以解释一下吗 gt gt gt x x 0 0 gt gt gt x gt gt gt x is x 0 True gt gt gt x 0 0 0 0 0 0 0 gt gt gt x in x True what is 这只是 P
  • OpenCV 3.0.0 使用 FFMPEG 时出错

    我使用 OpenCV 一段时间了 但是 我最近将系统更改为没有任何管理员权限的集群 问题是这样的 在我的主文件夹中 我安装了 FFMPEG ffmpeg 网站上提供的最新稳定版本 我将它安装在 HOME 中 因此在 HOME lib 中安装
  • sso 用户的 s3 存储桶策略

    我想允许特定角色 test role 在特定存储桶 test bucket 上执行所有 s3 操作 拒绝为所有其他人提供桶 我写的 s3 策略 Version 2012 10 17 Id Policy1601973417173 Statem
  • 以编程方式发送自动电子邮件[重复]

    这个问题在这里已经有答案了 我想以编程方式发送电子邮件 我尝试了以下代码 最终意图 emailIntent 新意图 android content Intent ACTION SEND emailIntent setType plain t
  • iOS:Firebase 令牌返回 null

    我目前正在尝试按照 Firebase 官方文档来实现 Firebase Cloud Messaging 我已在启用推送通知的情况下解决了证书和配置文件的问题 我还使用 CocoaPods 安装了所有必要的框架 FirebaseMessagi
  • 将 LinkBut​​ton 的 OnClick 事件设置为代码隐藏中的方法

    我正在从我的代码隐藏构造一个 LinkBut ton 我需要将 onclick 分配给一个方法 并用它传递一个参数 到目前为止我有这个 LinkButton lnkdel new LinkButton lnkdel Text Delete
  • 在 FIFO 上写入“复杂”结构

    我正在使用 C 语言与客户端服务器进行某种 餐厅 实现 我正在尝试通过 FIFO 发送以下结构 typedef struct int numtable table number to send answer char timestamp 2
  • 没有带有常量“模板参数”的 F# 泛型?

    我突然想到 F 泛型似乎不接受常量值作为 模板参数 假设有人想创建一种类型RangedInt这样 它的行为类似于 int 但保证只包含整数值的子范围 一种可能的方法是建立受歧视的工会 类似于 type RangedInt Valid of
  • 使用 ggplot 约束 stat_smooth 中的斜率(绘制 ANCOVA)

    Using ggplot 我试图绘制 ANCOVA 的结果 其中两个线性分量的斜率相等 即lm y x A 默认行为为geom smooth method lm 是为每个因子的每个水平绘制单独的斜率和截距 例如 有两个级别A library
  • 具有两个以上固定效应的 Python 面板数据回归

    我有一个面板数据库 想运行考虑固定效应的回归 使用Panel Ols 时 两个固定效果可以正常工作 我的代码如下所示 df countyCode pd Categorical df countyCode df state pd Catego
  • 如何从带有通配符的字符串中获取Appx全名?

    在 Powershell 中 此命令Get AppxPackage name 可以显示包裹的完整详细信息 是否可以使用任何 Windows API 来获得等效结果 我见过这个question https stackoverflow com
  • python cdist 错误 ValueError: XA 必须是二维数组

    这是我的代码的缩短版本 dist array ssd cdist test y training test y 打印的是 0 00000000e 00 1 79900000e 01 1 03800000e 01 1 22800000e 02
  • 在 SQL 中获取运行总计最大值的高性能方法

    我们有一个交易表 其结构如下 TranxID int PK and Identity field ItemID int TranxDate datetime TranxAmt money TranxAmt 可以是正数或负数 因此该字段 对于
  • PostgreSQL 对连接中的表数量有限制吗?

    今天在玩动态查询生成时 我发现 mysql 对连接中可以使用的表数量有一个硬性最大限制 61 这让我想知道 PostgreSQL 是否有类似的限制 注 我问这个是出于好奇 而不是需要 据我所知没有限制 一旦超过 可配置的 表限制 查询优化器
  • Spring Boot 安全 - Thymeleaf sec:授权不起作用

    我正在尝试使用 Spring Boot Spring Security 4 Thymeleaf 如果用户具有 admin 角色或其他角色 应该显示 html 块 但现在它始终显示在页面上 这是我的html div p class bg in
  • Python 中的“与”/“或”? [复制]

    这个问题在这里已经有答案了 我知道and and orpython中存在表达式 但是有没有and or表达 或者以某种方式将它们组合起来以产生与and or表达 我的代码看起来像这样 if input a if a or or or or
  • Django 在一次调用中序列化多个对象

    我想知道如何减少序列化时对数据库的调用次数 我有以下2个型号 class House models Model name models CharField max length 100 null True blank True addres