python - Django select_related does not work -
my django select_related works weirdly
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' output:
books = book.objects.select_related('publisher').all() print books.query select "book"."id", "book"."name", "book"."publisher_id", "publisher"."id", "publisher"."name" "book" inner join "publisher" on ( "book"."publisher_id" = "publisher"."id" ) print books.values() [{'publisher_id': 1, u'id': 1, 'name': u'rest framework'}] django generates correct query , data retrieved when execute it. values not contain publisher
you're misunderstanding how selected_related works. referring django docs on select_related:
select_relatedreturns queryset “follow” foreign-key relationships, selecting additional related-object data when executes query. this performance booster results in single more complex query means later use of foreign-key relationships won’t require database queries.
as determined, adding select_related causes django select related-object's data (publisher.id & publisher.name in case). however, all() method still return book queryset.
where useful when access book's publisher, django not need query database again publisher:
# hits database. # select "book"."id", "book"."name", "book"."publisher_id" ... b = book.objects.get(name='twilight') # hits database again related book object. # select "publisher"."id", "publisher"."name" ... p = b.publisher that's 2 database queries, whereas select_related lookup one:
# hits database, includes publisher data in 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 database, because b.publisher has been prepopulated # in previous query. p = b.publisher (example slight variation on django docs example)
Comments
Post a Comment