Django | 反向关系添加对象:多对一

在关联的模型中,比如多对一或者多对多这些类型,在某些场景下,比如简单快速为特定用户添加标签,为了快速添加对象,会使用反向添加,这里简单描述多对一场景下

django 1.10.3

1 非自定义模型主键

1.1 模型示例

@python_2_unicode_compatible
class Author(models.Model):
    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name


@python_2_unicode_compatible
class Posts(models.Model):
    headline = models.CharField(max_length=100)
    author = models.ForeignKey(Author, related_name="author_posts")

    def __str__(self):
        return self.headline

1.2 操作流程

In [6]: author2 = Author.objects.create(name='paul')

In [7]: post2 = Posts(headline='hello post2')

In [11]: author2.author_posts.add(post2, bulk=False)
BEGIN

Execution time: 0.000018s [Database: default]

INSERT INTO "apple_posts" ("headline",
                           "author_id")
VALUES ('hello post2',
        2)

Execution time: 0.000314s [Database: default]

重复添加同一实例
In [12]: author2.author_posts.add(post2, bulk=False)
BEGIN

Execution time: 0.000018s [Database: default]

UPDATE "apple_posts"
SET "headline" = 'hello post2',
    "author_id" = 2
WHERE "apple_posts"."id" = 3

Execution time: 0.000257s [Database: default]

这里添加要注意 bulk=False

2 自定义模型主键

2.1 模型示例

import uuid


class BaseBackBone(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid1().hex, editable=False, max_length=32)

    class Meta:
        abstract = True


@python_2_unicode_compatible
class AuthorWithId(BaseBackBone):
    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name


@python_2_unicode_compatible
class PostsWithId(BaseBackBone):
    headline = models.CharField(max_length=100)
    author = models.ForeignKey(AuthorWithId, related_name="author_posts")

    def __str__(self):
        return self.headline

2.2 操作流程

In [2]: author1 = AuthorWithId.objects.create(name='paul')

In [3]: post1 = PostsWithId(headline='hello post1 with id')

In [5]: author1.author_posts.add(post1, bulk=False)
BEGIN

Execution time: 0.000019s [Database: default]

UPDATE "apple_postswithid"
SET "headline" = 'hello post1 with id',
    "author_id" = '7d9d0f91ad6f11e6b0c1f45c89a84eed'
WHERE "apple_postswithid"."id" = '7d9d0f91ad6f11e6b0c1f45c89a84eed'

Execution time: 0.000141s [Database: default]

INSERT INTO "apple_postswithid" ("id",
                                 "headline",
                                 "author_id")
SELECT '7d9d0f91ad6f11e6b0c1f45c89a84eed',
       'hello post1 with id',
       '7d9d0f91ad6f11e6b0c1f45c89a84eed'

Execution time: 0.000291s [Database: default]

重复添加同一实例
In [6]: author1.author_posts.add(post1, bulk=False)
BEGIN

Execution time: 0.000021s [Database: default]

UPDATE "apple_postswithid"
SET "headline" = 'hello post1 with id',
    "author_id" = '7d9d0f91ad6f11e6b0c1f45c89a84eed'
WHERE "apple_postswithid"."id" = '7d9d0f91ad6f11e6b0c1f45c89a84eed'

Execution time: 0.001262s [Database: default]

3 总结

使用自定义主键添加对象时,数据库会多做一次查询操作,因为 Django 需要验证是更新还是插入操作。在使用自定义主键场景下,会增加数据库的查询操作。


黑月亮
点滴记录,步步成长

现实与完美之间

1.6k 声望
24 粉丝
0 条评论
推荐阅读
centos | 修改静态 IP
设置 Centos 为使用静态 IP1 修改网络配置 {代码...} 修改后的内容如下 {代码...} 2 重启网络服务 {代码...} 3 查看地址 {代码...} 参考来源:[链接]

青阳半雪阅读 1.8k评论 3

Mysql到TiDB迁移,双写数据库兜底方案
TiDB 作为开源 NewSQL 数据库的典型代表之一,同样支持 SQL,支持事务 ACID 特性。在通讯协议上,TiDB 选择与 MySQL 完全兼容,并尽可能兼容 MySQL 的语法。因此,基于 MySQL 数据库开发的系统,大多数可以平滑迁...

京东云开发者阅读 993

封面图
三、djanjo
Django 提示:本文根据b站黑马python课整理链接指引 => 黑马程序员python企业级开发项目-手把手从0到1开发《美多商城》视图介绍和项目准备视图介绍视图就是应用中views.py文件中的函数视图的第一个参数必须为H...

玲小叮当阅读 902

一、Django
Django 提示:本文根据b站黑马python课整理链接指引 => 黑马程序员python企业级开发项目-手把手从0到1开发《美多商城》一、Django介绍1.1 MVT模式M全拼为Model,与MVC中的M功能相同,负责和数据库交互,进行数...

玲小叮当阅读 795

Django笔记二十二之多数据库操作
在第十篇笔记的时候,简单介绍过 using() 的使用方法,多个数据库就是通过 using(db_alias) 的方式来来指定选中的数据库,这里介绍一下同步库表结构时候的操作。

Hunter阅读 767

封面图
Django笔记十三之select_for_update等选择和更新等相关操作
本篇笔记将介绍 update 和 create 的一些其他用法,目录如下:get_or_createupdate_or_createselect_for_updatebulk_createbulk_update1、get_or_create前面我们介绍过 get() 和 create() 的用法,那么 get_or_cr...

Hunter阅读 714

封面图
Django笔记十二之defer、only指定返回字段
defer 的英语单词的意思是 延迟、推迟,我们可以通过将字段作为参数传入,可以达到在获取数据的时候指定不获取该字段数据,常用于一些 textfield 字段上。

Hunter阅读 680

封面图

现实与完美之间

1.6k 声望
24 粉丝
宣传栏