『Django ORM』完整总结

因为官方文档通常讲究『平均发力,面面俱到』,虽然内容是详细,可是对于初学者每每是『不知轻重,找不着北』。本文试图总结一些 Django ORM 中比较经常使用的东西,力求覆盖全面,实现『花20%的时间,搞定80%的内容』的目的。python

【ORM class 的定义】

这个很是简单,基本无脑使用。注意,这里我假设:使用者基本不使用『物理层外键』,外键逻辑再应用层控制(这个话题见仁见智,各有各的选择)。数据库

【建立】

有二者风格,一种是:django

# 一开始就直接把属性所有列举出来, 并建立对象
blog_orm = Blog(title="xxx", name="xxx", ...)
blog_orm.save()
复制代码

另外一种是:bash

# 先将对象建立出来,虽然再根据要求(条件),填充对应的属性。
blog_orm = Blog()
blog_orm.title = "xxx"
if some_condition:
    blog_orm.name = "yyy"

blog_orm.save()
复制代码

两种方式没有优劣,可是第二种更加常见,由于通常数据库表有许多字段,建立ORM对象时,那个时间点的上下文,是并不能获取到某些属性,这些属性多是后续根据某些条件生成的,或者依赖一些特定的参数。学习

【查询】

Django ORM的查询,基本上算是一门小的 DSL 了,并且只适用于 Django ORM,并不能迁移到其余领域,对于我的而言,这种东西,属于价值比较有限的东西,花太多力气学习是不值得的。相比之下,多发点时间了解 SQL ,可能更加有价值,由于它的适用范围更加普遍。ui

  1. 记住几个个API。Django ORM的 API很是统一,这是比较好的消息。
.filter(**kw)           正面条件,好比 等于/大于
.exclude(**kw)          方面条件,好比 不能于/不是
Q(**kw)                 OR 逻辑,好比条件1 或者 条件2,使用形式为: Q(name="xxx") | Q(sex="yyy"复制代码
  1. 风格分为两种。
第一种:求出QuerySet。
这是最经常使用,也最实用的, 由于QuerySet 有很是完备系统的API,后文详述之。若是没有特殊状况,通常使用这种方式
好比:user_qs = User.objects.filter(name="xxx").filter(sex="yyy").exclude(age=22)

第二种:直接求值出来,即 .first() .all()这些方法
这种通常只在特定并且肯定的状况下,才去使用,范围比较受限
好比:
    user_qs = 
    one_user_obj = user_qs.first()
    all_user_objs = user_qs.all()
复制代码
  1. 并不须要特别记忆的『Lookup Expression』
无非是映射到SQL的WHERE中的条件而已,用几回就熟悉了。
Django文档,有个专门的连接讲这个东西,即使如此,经常使用的也就那么几个。
复制代码
  1. LIMIT OFFSET
这个须要特别发点时间去记忆。
一直不明白,Django 为何不提供 .offset() .limit() 这样的 API,而是搞成『很照顾Python习惯』的切片方式,
这样,虽然照顾了『Python的习惯』,可是使用中不免有点心智上的负担,由于他的大脑须要自动映射到SQL的 OFFSET/LIMIT,

一直以为,ORM不该该搞太厚的逻辑,也不要夹带太多私货,一切应该以『照顾SQL的习惯』为基准。
复制代码

【修改】

  1. 单个修改
这个很是简单易用
user_obj.name = "new_name"
user_obj.save()
复制代码
  1. 批量修改
对符合某一组查询条件的ORM对象列表,进行批量更新
user_qs = 
user_qs.udpate(name="new_name")
复制代码

【删除】

  1. 单个删除:user_obj.delete()
  2. 批量删除
user_qs = 
user_qs.delete()
复制代码

【事务】

这个绝对是很是重要的,不是由于再Django中这个东西重要,而是由于这个东西自己就重要,跟Django不Django没有半点关系。atom

再Django中使用,很是简单:spa

from django.db import transaction
with transaction.atomic():
    do_more_stuff()
复制代码
相关文章
相关标签/搜索