django ORM

更新日期: 2015-12-12 阅读次数: 5554 分类: Django

ORM

一直不喜欢用 ORM 做复杂关系,原因是不了解 ORM 对应的数据库表结构。 以及新建 Model 对象时,一些复杂属性如何初始化。

ForeignKey

在 SQLite 中,Foreign Key 对应的只是一个数字, 例如

owner = models.ForeignKey(User, null=True)   

.schema 之后会发现

"owner_id" integer,

ManyToMany

例如,model 里增加一个 ManyToManyField

tags = models.ManyToManyField(Tag) 

实际上是新增了一个关系表

CREATE TABLE "<app-name>_<model-name>_tags" (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
    "<model-name>_id" integer NOT NULL,
    "tag_id" integer NOT NULL REFERENCES "<app-name>_tag" ("id"),
    UNIQUE ("<table-name>_id", "tag_id")
);
CREATE INDEX "<app-name>_<model-name>_tags_b96e4040" ON "<app-name>_<model-name>_tags" ("<model-name>_id");
CREATE INDEX "<app-name>_<model-name>_tags_5659cca2" ON "<app-name>_<model-name>_tags" ("tag_id");

所以,要建立这个关系,首先要 save 一个 model, 再 save 一个 tag, 然后在 add tag,再 save。 如果之前的 model, tag 不 save,就没法获取 id。

为了避免 tag 被重复创建,可以先检测 tag 是否存在,然后再创建。

try:
    obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
    obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
    obj.save()

简化为

obj, created = Person.objects.get_or_create(first_name='John', last_name='Lennon',
                  defaults={'birthday': date(1940, 10, 9)})

created 代表是否是新创建的, 参考

领取阿里云/腾讯云服务器优惠券

关于作者

我是来自山东烟台的一名开发者,喜欢瞎折腾,顺便记记笔记。有敢兴趣的话题,欢迎加微信 zhongwei 聊聊。 白天写程序,晚上哄熊孩子,可能回复有点慢,见谅。 查看更多联系方式

相关文章

爱评论不评论

近期节日

2020年10月01日 国庆节
2020年10月01日 中秋节
2020年10月04日 世界动物日
2020年10月08日 寒露
2020年10月09日 世界邮政日
2020年10月10日 辛亥革命纪念日
2020年10月13日 中国少年先锋队诞辰日
2020年10月14日 世界标准日
2020年10月15日 国际盲人节
2020年10月16日 世界粮食日
2020年10月17日 国际消除贫困日
2020年10月22日 世界传统医药日
查看更多节日