Python django与model的性质
我有个问题。这两个属性的工作方式是否不同?我指的是db hits。 例如,我们有一个模型文章,它有一个Python django与model的性质,python,django,Python,Django,我有个问题。这两个属性的工作方式是否不同?我指的是db hits。 例如,我们有一个模型文章,它有一个ForeignKey字段book from django.db import models class Article(models.Model): book = models.ForeignKey("books.Book") 通过以下供应商之一获得作者的最佳方式是什么: @property def author(self): if self.book: re
ForeignKey
字段book
from django.db import models
class Article(models.Model):
book = models.ForeignKey("books.Book")
通过以下供应商之一获得作者的最佳方式是什么:
@property
def author(self):
if self.book:
return self.book.author
return None
或
你应该打个电话
article.book.author
此调用将查询book对象并将其缓存在article实例上。因此,如果在第一次调用之后调用article.book.id,它将不会运行第二次查询
我个人认为,您应该尽量避免在模型方法中影响数据库。因为,当您的应用程序变得复杂时,开发人员将只调用您文章的author方法,即使他们手中也有书籍模型。因为两个属性实际上是相同的 因为您是在文章
上定义属性,所以实际的数据库命中率取决于如何检索文章
查询集。如果在检索文章
对象时在上使用select_related([depth=2])
,则无论如何编写属性,在数据库命中率方面,这都是最理想的。您列出的两种方法的性能相似。我更喜欢此选项,因为它只对数据库进行一次查询:
@property
def author(self):
authors = Author.objects.filter(book__article=self.id)[:1]
return authors[0] if authors else None
从django和python的角度来看,这是相等的。真正的成功在于你的queryset方法。我不确定我是否理解你的问题。你的两个选择在功能上与我完全相同。我会选择选项一,因为它少了一条线。它们都需要两个查询:一个用于author对象,一个用于book。但是,如果使用select_related()选择author对象,则可以将其设置为一个,该对象将预加入书籍。但是,无论是否使用select_related
,此解决方案都将始终进行查询。是的,但有时它是首选选项。此外,如果您确信在这个过程中requestauthor
字段不会更改,您可以使用类似@memomeized_property
的内容,而不是@defuz属性
@defuz有时还不够好,请给出一个具体的示例,如果您愿意,请给出一个很好的理由。我看不出这有什么好处。@KillianDS,1。当我们选择文章
时,我们不知道每个文章模型是否需要作者
。2.通过book
table连接tablesauthor
可能是一个昂贵的操作(即使使用索引)。@defuz:这是select\u related
的一个缺点,而不是为什么不使用原始代码(显然比这要清楚得多)。另外,您多长时间检索一整套书籍,但只检索一本书的作者。如果book
是None
,该怎么办?然后将抛出AttributeError:'NoneType'对象没有属性“author”
。我同意你关于模型内部查询的说法。你真的指出了很多人看不到的好东西。
@property
def author(self):
authors = Author.objects.filter(book__article=self.id)[:1]
return authors[0] if authors else None