Django select_related方法使用

Django select_related方法使用


Returns a QuerySet that will automatically "follow" foreign-key relationships, selecting that additional related-object data when it executes its query. This is a performance booster which results in (sometimes much) larger queries but means later use of foreign-key relationships won't require database queries.

The following examples illustrate the difference between plain lookups and select_related() lookups. Here’s standard lookup:

# Hits the database.
e = Entry.objects.get(id=5)

# Hits the database again to get the related Blog object.
b = e.blog
And here’s select_related lookup:

# Hits the database.
e = Entry.objects.select_related().get(id=5)

# Doesn’t hit the database, because e.blog has been prepopulated
# in the previous query.
b = e.blog
select_related() follows foreign keys as far as possible. If you have the following models:

class City(models.Model):
# …
pass

class Person(models.Model):
# …
hometown = models.ForeignKey(City)

class Book(models.Model):
# …
author = models.ForeignKey(Person)
…then a call to Book.objects.select_related().get(id=4) will cache the related Person and the related City:

b = Book.objects.select_related().get(id=4)
p = b.author # Doesn’t hit the database.
c = p.hometown # Doesn’t hit the database.

b = Book.objects.get(id=4) # No select_related() in this example.
p = b.author # Hits the database.
c = p.hometown # Hits the database.
Note that, by default, select_related() does not follow foreign keys that have null=True.

Usually, using select_related() can vastly improve performance because your app can avoid many database calls. However, in situations with deeply nested sets of relationships select_related() can sometimes end up following “too many” relations, and can generate queries so large that they end up being slow.

In these situations, you can use the depth argument to select_related() to control how many “levels” of relations select_related() will actually follow:

b = Book.objects.select_related(depth=1).get(id=4)
p = b.author # Doesn’t hit the database.
c = p.hometown # Requires a database call.
Sometimes you only want to access specific models that are related to your root model, not all of the related models. In these cases, you can pass the related field names to select_related() and it will only follow those relations. You can even do this for models that are more than one relation away by separating the field names with double underscores, just as for filters. For example, if you have this model:

class Room(models.Model):
# …
building = models.ForeignKey(…)

class Group(models.Model):
# …
teacher = models.ForeignKey(…)
room = models.ForeignKey(Room)
subject = models.ForeignKey(…)
…and you only needed to work with the room and subject attributes, you could write this:

g = Group.objects.select_related(‘room’, ‘subject’)
This is also valid:

g = Group.objects.select_related(‘room__building’, ‘subject’)
…and would also pull in the building relation.

You can refer to any ForeignKey or OneToOneField relation in the list of fields passed to select_related(). This includes foreign keys that have null=True (which are omitted in a no-parameter select_related() call). It’s an error to use both a list of fields and the depth parameter in the same select_related() call; they are conflicting options.

Changed in Django 1.2: Please see the release notes
You can also refer to the reverse direction of a OneToOneField in the list of fields passed to select_related — that is, you can traverse a OneToOneField back to the object on which the field is defined. Instead of specifying the field name, use the related_name for the field on the related object.

A OneToOneField is not traversed in the reverse direction if you are performing a depth-based select_related() call.

发表评论

电子邮件地址不会被公开。 必填项已用*标注