user1328021
user1328021

Reputation: 9850

Django query optimization with a ManytoMany Field

I found that this one bit of code (in bold) in my template produces ~250 queries and makes things REALLY slow:

{% for part in latestupdates %}
{{ part }}
      **{% for unipart in part.uniparts.all|slice:":5" %}**
      <tr>
        <td>
            <p style ="font-size:12px;"><a href = "/spices/{{ unipart_id }}/view_part">{{ unipart.part }}</a></p></td>
        <td><img src="{{ STATIC_URL }}images/company_logos/thumbs/{{part.model.all.0.manufacturer}}.jpg" alt="{{part.model.all.0.manufacturer}} {{unipart.part}}" height="24" width='115' /></td>
      </tr>
      {% endfor %}
{% endfor %}

The relationship between Unipart and Part is as follows:

class UniPart (models.Model):
    model = models.ManyToManyField (Part, related_name = 'uniparts')

My view is as follows:

latestupdates = Part.objects.all().order_by('-added')

Basically what I want to is get 5 Unipart objects that link to Part. But this is costing me big time!!! What is a more efficient way to do than what I did? I actually have >600 database queries which is pretty pathetic and I'm reading up on database optimization but for this bit I can't find anything relevant. Help! :-)

Upvotes: 1

Views: 1292

Answers (1)

Pol
Pol

Reputation: 25585

Try prefetch_related() the method of QuerySet.

latestparts = Part.objects.all().prefetch_related('uniparts').order_by('-added')

But pay attention on amount of items you trying to prefetch. Because it can overwlow you memory.

And yes this works only in django 1.4 I think.

Use select_related() if you have models.ForeignKey field (not your case). This works in older version of django.

Upvotes: 3

Related Questions