List Info

Thread: select_related() including a distant many_to_many




select_related() including a distant many_to_many
user name
2008-02-23 17:22:29
Hi;

For an app that describes Wine Competitions, I have a model
that
includes:

class Awardswon(models.Model):
    competition = models.ForeignKey(Competition,
verbose_name="Competition")
    wine = models.ForeignKey(Wine,
verbose_name="Wine")
    awardname = models.ForeignKey(Awardname,
verbose_name='Award')
    score = models.CharField(blank=True,maxlength=10)


class Wine(models.Model):
    class_number = models.CharField(blank=True,
maxlength=100)
    wine_name = models.CharField(blank=True, maxlength=100,
db_index=True)
    varietal = models.ManyToManyField(Varietal)
    <snip>


class Varietal(models.Model):
    varietal = models.CharField(blank=False, maxlength=100)


I'm able to display Wines that have won a specific award,
with their
associated varietal information:


def loadWinners(request,award,comp):
    errorText = ""
    if comp and award:
        c = Competition.objects.get(pk=comp)
        aw =
Awardswon.objects.select_related().filter(competition=comp).
order_by('-
score')
        aw = aw.filter(awardname=award)
        awn = Awardname.objects.get(pk=award)
        if len(aw)==0:
           errorText = "Nothing Found"
    else:
        aw=[]
        c=[]
        awn=[]
    return
render_to_response("winelist.html",{"aw"
:aw,
"mediaurl":settings.SITE_MEDIA_PREFIX,"error&
quot;:errorText,"c":c,"awn":awn})

And the view includes

{% for wine_aw in aw %}
	<li><a
href="/wine/{{wine.wine.id}}">{{wine_aw.wine}}&
lt;/a>
({{wine_aw.wine.varietal.all|join:","}})
{{wine_aw.score}}</li>
{% endfor %}

Earlier I'd added StatsMiddleware and followng the author's
discussion
learned about select_related. (Thanks).

But, using that tool, it seems that the many-to-many data
isn't loaded
in the initial query. That is, django does a query for each
awarded
wine to get the related varietals.

Is there a way to load the varietals as part of the initial
query?

Thanks.


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


Re: select_related() including a distant many_to_many
country flaguser name
Australia
2008-02-23 18:02:28

On Sat, 2008-02-23 at 15:22 -0800, Lee Hinde wrote:
> Hi;
> 
> For an app that describes Wine Competitions, I have a
model that
> includes:
> 
> class Awardswon(models.Model):
>     competition = models.ForeignKey(Competition,
> verbose_name="Competition")
>     wine = models.ForeignKey(Wine,
verbose_name="Wine")
>     awardname = models.ForeignKey(Awardname,
verbose_name='Award')
>     score = models.CharField(blank=True,maxlength=10)
> 
> 
> class Wine(models.Model):
>     class_number = models.CharField(blank=True,
maxlength=100)
>     wine_name = models.CharField(blank=True,
maxlength=100,
> db_index=True)
>     varietal = models.ManyToManyField(Varietal)
>     <snip>
> 
> 
> class Varietal(models.Model):
>     varietal = models.CharField(blank=False,
maxlength=100)
> 
> 
> I'm able to display Wines that have won a specific
award, with their
> associated varietal information:
> 
> 
> def loadWinners(request,award,comp):
>     errorText = ""
>     if comp and award:
>         c = Competition.objects.get(pk=comp)
>         aw =
>
Awardswon.objects.select_related().filter(competition=comp).
order_by('-
> score')
>         aw = aw.filter(awardname=award)
>         awn = Awardname.objects.get(pk=award)
>         if len(aw)==0:
>            errorText = "Nothing Found"
>     else:
>         aw=[]
>         c=[]
>         awn=[]
>     return
render_to_response("winelist.html",{"aw"
:aw,
>
"mediaurl":settings.SITE_MEDIA_PREFIX,"error&
quot;:errorText,"c":c,"awn":awn})
> 
> And the view includes
> 
> {% for wine_aw in aw %}
> 	<li><a
href="/wine/{{wine.wine.id}}">{{wine_aw.wine}}&
lt;/a>
> ({{wine_aw.wine.varietal.all|join:","}})
{{wine_aw.score}}</li>
> {% endfor %}
> 
> Earlier I'd added StatsMiddleware and followng the
author's discussion
> learned about select_related. (Thanks).
> 
> But, using that tool, it seems that the many-to-many
data isn't loaded
> in the initial query. That is, django does a query for
each awarded
> wine to get the related varietals.
> 
> Is there a way to load the varietals as part of the
initial query?

Not without writing custom SQL at the moment.
select_related() only
follows non-null many-to-one relations. One day we might add
this
support (many-to-many, one-to-many, etc), but we need to
build in "don't
shoot yourself in the foot" protection so that people
don't accidentally
try to query multiple such relations at once, for example.

Malcolm

-- 
He who laughs last thinks slowest. 
http://www.pointy-s
tick.com/blog/


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


[1-2]

about | contact  Other archives ( Real Estate discussion Medical topics )