django ORM

文章目录

    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 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式