django ORM

更新日期: 2015-12-12 阅读次数: 6523 分类: 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 代表是否是新创建的, 参考

爱评论不评论