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 需要验证是更新还是插入操作。在使用自定义主键场景下,会增加数据库的查询操作。

未登录用户
全部评论0
到底啦