【问题标题】:Django select_related does not workDjango select_related 不起作用
【发布时间】:2014-07-23 00:42:03
【问题描述】:

我的 django select_related 工作很奇怪

Models:
class Publisher(models.Model):
 name = models.CharField(max_length=100)
 class Meta:
      app_label = 'models'
      db_table = 'Publisher'
class Book(models.Model):
 name = models.CharField(max_length=100)
 publisher = models.OneToOneField(Publisher)
 class Meta:
      app_label = 'models'
     db_table = 'Book'

输出:

books = Book.objects.select_related('publisher').all()
print books.query
SELECT "Book"."id", "Book"."name", "Book"."publisher_id", "Publisher"."id", "Publisher"."name" FROM "Book" INNER JOIN "Publisher" ON ( "Book"."publisher_id" = "Publisher"."id" )
print books.values()
[{'publisher_id': 1, u'id': 1, 'name': u'rest framework'}]

Django 生成正确的查询,并在我执行时检索数据。但值不包含 Publisher

【问题讨论】:

标签: python django django-orm


【解决方案1】:

您对selected_related 的工作方式略有误解。参考django docs on select_related

select_related 返回一个“遵循”外键关系的 QuerySet, 在执行查询时选择其他相关对象数据。 这是一个性能提升器,它会导致一个更复杂的 查询但意味着以后不需要使用外键关系 数据库查询。

正如您已经确定的那样,添加 select_related 会导致 django 选择相关对象的数据(在本例中为 Publisher.idPublisher.name)。但是,all() 方法仍然只会返回一个Book QuerySet。

当您访问BookPublisher 时,这很有用,django 不需要再次查询数据库以获取Publisher

# Hits the database.
# SELECT "Book"."id", "Book"."name", "Book"."publisher_id" ...
b = Book.objects.get(name='Twilight')

# Hits the database again to get the related Book object.
# SELECT "Publisher"."id", "Publisher"."name" ...
p = b.publisher

这是两个数据库查询,而 select_related 查找只有一个:

# Hits the database, but already includes Publisher data in the query
# SELECT "Book"."id", "Book"."name", "Book"."publisher_id", "Publisher"."id", "Publisher"."name" ...
b = Entry.objects.select_related('publisher').get(name='Twilight')

# Doesn't hit the database, because b.publisher has been prepopulated
# in the previous query.
p = b.publisher

(示例与django docs 示例略有不同)

【讨论】:

  • 你为什么在你的例子中使用'Entry'?
猜你喜欢
  • 1970-01-01
  • 2016-07-02
  • 2011-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多