Django使用相关对象作为kwarg的update_or_create(获取部分)

时间:2019-04-03 11:06:26

标签: python django django-queryset

我正在执行update_or_create queryset操作,该操作在内部使用get queryset操作。我已经阅读了有关update_or_create queryset方法的文档,但是在理解与外键有关的部分以及将对象用作kwarg时遇到了一些困难。

考虑一个示例,其中有模型Book和Chapter,并且执行以下操作:

book = Book.objects.get(...)

kwargs = {'book': book, 'name': 'Chapter 3'}
defaults = {'text': '...'}
Chapter.objects.update_or_create(defaults=defaults, **kwargs)

现在,将在'get'方法中使用kwarg检查该章节是否存在。但是,由于书是对象,因此Django如何知道是否存在与“匹配”书对应的章节?是否检查书籍对象的所有字段是否匹配?它仅检查唯一字段吗?只有这本书的主键?如果我有两本书具有相同的字段但主键不同,它们可以匹配吗?以这种方式在kwarg中使用对象是一种好习惯,还是冒着出现完整性错误问题的风险?谢谢。

2 个答案:

答案 0 :(得分:2)

在这里,kwargs只是一个字典,当您在其前面使用**时,这意味着这些值将被解包并像这样传递:

kwargs = {'book': book, 'name': 'Chapter 3'}
Chapter.objects.update_or_create(defaults=defaults, **kwargs)

转换为(作为关键字参数传递的值):

Chapter.objects.update_or_create(defaults=defaults,book=book, name="Chapter 3")

现在,django在章节中匹配书籍的主键。如果两个书本对象之间的主键不同,则意味着它们是不同的对象,而不管其其他字段是否相同。

答案 1 :(得分:1)

在上下文中,我假设Chapter具有Book的FK。

在这种情况下,Django将使用字段ID,或者如果您更改了默认设置,则使用书本实例中的主键进行匹配。等同于:

Chapter.objects.update_or_create(defaults=defaults, book=book.id)

因此,除了主键之外,您有数百本书的字段完全相同,django会知道如何处理。