作为一只以 Django 作为主力开发框架的 CRUD Boy ,时常和它的 ORM 缠绵悱恻、纠缠不清,特此记录一下这些笑与泪的记忆。

魔鬼的陷阱

QuerySet 的类型

有时候希望它简单一点

objects.values() 返回的并不是简单类型的数据,而是 QuerySet。一般直接用来做 Response 没有问题,但是要知道 QuerySet 是不能被 pickle 的,如果使用到 Django Cache 之类功能,直接用 values() 当作返回会死得很惨。

有时候希望它坚持自我

很多时候我们需要限制 QuerySet 返回的字段以加快 DB 查询的速度(比如一些没索引的长字段),这时候可能的两个方法: only() & values()

但实际情况是,使用 values() 会改变 queryset._iterable_class ,如果后面还有更多的级联查询,会导致最后的结果为 Dict 而不是 QuerySet

多对多和 values()

存在一个模型

class Foo(models.Model):
    name = models.CharField(**some_params)
    bars = models.ManyToManyField(**some_params)

存在一条记录

foo:
  name: tom
  bars:
    - a
    - b 

values() 预期返回

[
    {
        "name": "tom",
        "bars": ["a", "b"]
    }
]