我正在执行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中使用对象是一种好习惯,还是冒着出现完整性错误问题的风险?谢谢。
答案 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会知道如何处理。