Alex Pavlov
Alex Pavlov

Reputation: 581

Django select related

I want to display all categories with related merchants and related merchant's image. How can I do this?

models.py

class Category(models.Model):
    title = models.CharField(max_length = 50)
    class Meta:
        verbose_name_plural = 'Categories'

class Merchant(models.Model):
    category = models.ForeignKey('Category', related_name = 'merchants', blank = True, null = True)
    title = models.CharField(max_length = 100)

class StoredFile(models.Model):
    merchant = models.OneToOneField(Merchant, related_name="_image", blank = True, null = True)

views.py

categories = Category.objects.select_related()

index.html

{% for category in categories %}
    {{ category.title }}
    {% for merchant in category.merchants  %}
        {{ merchant.name }}
        {{ merchant.image.url }}
    {% endfor %}
{% endfor %}

My code doesn't work.

'RelatedManager' object is not iterable.

I guess related query is wrong.

Upvotes: 0

Views: 900

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599610

The related query is wrong, but that is not the cause of your error. That is because you need to use a related manager with all() or filter(), just like any other manager.

{% for merchant in category.merchants.all %}

Note that this works whether or not you do any special related queries in the view; this syntax is always available, and select_related does not give access to any more attributes. All it does is make the query more efficient.

However in your case select_related is not even the correct thing to use; it will have no effect. That's because it only works for forward relations, and you have reverse relations from Category to Merchant. You need prefetch_related for that.

categories = Category.objects.prefetch_related('merchants')

Upvotes: 1

Related Questions