2014-06-02 3 views
2

Мои Джанго select_related работает очень удачливыйДжанго 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'}] 

Джанго генерирует правильный запрос и данные извлекаются, когда я исполню ее. Но значения не содержат Издатель

+0

Проверьте это отве er http://stackoverflow.com/questions/1211349/how-to-combine-select-related-and-value –

ответ

3

Вы слегка недопонимаете, как работает selected_related. Ссылаясь на django docs on select_related:

select_related возвращает QuerySet, который будет «следовать» внешнего ключа отношения, выбора дополнительных данных, связанных с-объекта, когда он выполняет свой запрос. Это ускоритель производительности, который приводит к одному более сложному запросу , но означает . Использование внешних ключей не потребует запросов к базе данных.

Как вы уже определили, добавив select_related причины Джанго для выбора данных со связанным объектом (Publisher.id & Publisher.name в данном случае). Однако метод all() по-прежнему будет возвращать только QuerySet Book.

Где это полезно, когда вы получаете доступ к Book «s Publisher, Джанго не нужно будет запрашивать базу данных снова для 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 примере)

+0

Почему вы используете «Entry» в вашем примере? –

Смежные вопросы