The purpose of select_related() is to limit the number of connections
to the database server.
An analogy would be that if you have a webpage with 4 CSS file
inclusions ( <link rel="stylesheet" ... ), it will make 4 HTTP
requests to the webserver. What you would do is to take those 4 files
and save them to one to reduce the number of requests to your web
server. select_related() does the same for the database.
What you have to understand is that you don't need select_related() to
display data from ForeignKeys (even in the templates), the Django DB
API will follow them for you if they are needed.
Here is an example:
I am fetching a message for a user, the message model looks like this:
class Message(models.Model):
"""
Model for inbox and outbox
"""
sender = models.ForeignKey(User, verbose_name=_('sender'),
related_name='outbox')
recipient = models.ForeignKey(User, verbose_name=_('recipients'),
related_name='inbox')
# ...
Without select_related() it makes 3 database calls:
>>> from pm.models import Message
>>> from django.db import connection
>>> message = Message.objects.get(pk=1)
>>> '%s sent a message to %s' % (message.sender.username, message.recipient.user
name)
u'admin sent a message to admin'
>>> len(connection.queries)
3
>>>
With select_related(), only one:
>>> from pm.models import Message
>>> from django.db import connection
>>> message = Message.objects.select_related().get(pk=1)
>>> '%s sent a message to %s' % (message.sender.username, message.recipient.user
name)
u'admin sent a message to admin'
>>> len(connection.queries)
1
>>>
The footnote of the select_related chapter is very important:
http://www.djangoproject.com/documentation/db-api/#select-related
Note that 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.
The depth argument is new in the Django development version.
On Nov 20, 9:22 am, Jarek Zgoda <[EMAIL PROTECTED]> wrote:
> Greg_IAP napisaĆ(a):
>
>
>
> > Hello,
>
> > i have 3 classes.
>
> > class Image(models.Model):
> > name = models.CharField(max_length = 20,blank=True)
> > instrument = models.ForeignKey(Instrument,null=True,blank=
> > True,db_column='instrument_id')
> > channel = models.ForeignKey(Channel,null=True,blank=
> > True,db_column='channel_id')
> > ...
>
> > class Instrument(models.Model):
> > name = models.CharField(max_length = 240, blank=True)
> > ...
>
> > class Channel(models.Model):
> > name = models.CharField(max_length = 80,blank=True)
> > ...
>
> > I just want to make a join through this tables with the select_related
> > to be able to print Image.name, Instrument.name, Channel.name
>
> The docs say select_related() does not follow foreign keys that have
> null=True. In your example it would do nothing.
>
> --
> Jarek Zgoda
> Skype: jzgoda | GTalk: [EMAIL PROTECTED] | voice: +48228430101
>
> "We read Knuth so you don't have to." (Tim Peters)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---