On Wed, Apr 25, 2012 at 4:43 PM, Lee Hinde <leehi...@gmail.com> wrote:
>
> On Apr 25, 2012, at 2:16 AM, Tom Evans wrote:
>
>> On Wed, Apr 25, 2012 at 5:58 AM, Lee Hinde <leehi...@gmail.com> wrote:
>>> I have a table with four or five foreign keys. Using the default form
>>> widgets, a foreign key is represented by a single value select.
>>>
>>> I noticed, with debug_tool_bar, that a query is being made for each
>>> element of each foreign key select option. Seems like it ought not
>>>
>>> I am using
>>>
>>>     classes = get_object_or_404(Classes, pk=pk)
>>>
>>> to load the record. I tried
>>> Classes.on_site.select_related().get(pk=pk) without any change.
>>>
>>> The question is, is this to be expected?
>>>
>>
>> Yes. How else would it get the potential values that can be selected?
>>
>> If you want to load all in one query, you can use select_related(). If
>> select_related() doesn't help, then your foreign keys are probably
>> nullable, which are not automatically loaded with select_related().
>>
>> FYI, having each foreign key lookup as a separate query may not be a bad 
>> thing.
>> If the cardinality of the foreign keys doesn't change much (you don't
>> add frequently add potential new values for that foreign key), then it
>> is highly likely that those queries would be served from the query
>> cache.
>>
>> If you are displaying 1 million different forms, but all their foreign
>> key lookups can be served from cache, do you think it would be quicker
>> to do 1 million queries with 5 joins in each query, with none of the
>> queries cached, or 5 million queries, 1 million with no joins and 4
>> million served from the query cache?
>>
>> Cheers
>>
>> Tom
>>
>
>
> Thanks Tom; I may have been unclear. I would expect at least one query per 
> foreign key to load the potential values, but there is a query for each 
> potential value. i.e.., one of the foreign keys is to an instructor table. 
> There's that query, then there's a query for each instructor as part of the 
> class page load.
>
> And yes, I have a lot of nullable foreign keys. In this example, I can have a 
> class but not know yet who the instructor will be. I suppose an alternative 
> to a nullable key would be to have a default, 'no decision made yet' option. 
> Thanks also for the reminder about select_related not following a nullable fk.
>

When turning an instance of an object into a <option> element, Django
calls the unicode function on that instance. If your __unicode__
method for that object references related objects, then Django will
have to issue a query for each instance.

Eg, if you had a models like this:

class Store(Model):
  name = CharField()
  region = ForeignKey('Region')

class Region(Model):
  name = CharField()
  country = ForeignKey('Country')
  def __unicode__(self):
    return u'%s (%s)' % (self.name, self.country.name)

class Country(Model):
  name = CharField()

and you were displaying a form for a Store instance, it would do one
query to look up all the related regions, but when it comes to render
the region options, it will issue an extra query per region in order
to look up the country name.

Remember that select_related() will happily follow nullable foreign
keys, you just have to explicitly ask for it by specifying the
relations you want loaded.

Cheers

Tom

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to