Pete Drennan
Pete Drennan

Reputation: 522

Finding a set of related items in Django

In Django, I am using the following code to get images related to a Location from the LocationImage model.

{% for location in locations %}
{% for image in location.locationimage_set.all %}
etc

If that location is a region, and there are no images for that region, I want to be able to get images for cities in that region, by still referring to only that region.

cities are also part of the location model, with a region field set to the region and related_name='location_region'

Any ideas on how to do this?

For example, if I had a region field in my LocationImage model, how would I refer to a set of all LocationImages with that region id in the region field, not in the main id field.

As requested, models:

class LocationImage(models.Model):
    location = models.ForeignKey(Location)
    imagelink = models.URLField(max_length=500, null=True)

class Location(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=200, db_index=True, verbose_name="ascii name")
    slug = models.SlugField(max_length=200)
    locationtype = models.CharField(max_length=50)
    region = models.ForeignKey('self', null=True, blank=True, related_name='location_region')
    country = models.ForeignKey('self', null=True, blank=True, related_name='location_country')

where locationtype = 'city', 'region or 'country'

Upvotes: 0

Views: 117

Answers (1)

catavaran
catavaran

Reputation: 45585

You can use the {% for %} ... {% empty %} template tag.

{% for location in locations %}
    {% for image in location.locationimage_set.all %}
        ...
    {% empty %}
        {# there is no images for `location` #}
        {% ifequal location.locationtype 'region' %}
            {% for city in location.location_region.all %}
                {% for image in city.locationimage_set.all %}
                    ...
                {% endfor %}
            {% endfor %}
        {% endifequal %}
    {% endfor %}
{% endfor %}

But I think this is too complex template code. May be it will be better to add get_images() method to the Location model and implement this logic in python?

class Location(models.Model):

    def get_images(self):
        images = self.locationimage_set.all()
        if self.locationtype == 'region' and not images:
            images = LocationImage.objects.filter(location__region=self)
        return images

This method is much more efficient than the template version. And the template will be as simple as:

{% for location in locations %}
    {% for image in location.get_images %}
        ...
    {% endfor %}
{% endfor %}

Upvotes: 3

Related Questions