简体   繁体   中英

Python / Django / Jinja2: How to extend a variable name with the value of another variable (e.g. in a for-loop)?

In my django db model I have eg 5x ImageField , which I want to use for a carousel in the front end:

slider_image_1 = models.ImageField(upload_to='images/', blank=True)
slider_image_2 = models.ImageField(upload_to='images/', blank=True)
slider_image_3 = models.ImageField(upload_to='images/', blank=True)
slider_image_4 = models.ImageField(upload_to='images/', blank=True)
slider_image_5 = models.ImageField(upload_to='images/', blank=True)

Depending whether the images were uploaded or not, I want to display the images and I am looking for an approach similar to something like this:

{% for FOO in range(5) %}
    {% if object.slider_image_|extend_name_with:FOO %}
        <img src="{{ object.slider_image_|extend_name_with:FOO.url }}">
    {% endif %}
{% endfor %}

Is something similar possible? What are other good approaches for this problem?

The recommended approach for complex logic in templates is to write the logic in a model method, rather than in the template itself.

In your case, I think this is what you want:

class SomeModel(models.Model):
    slider_image_1 = models.ImageField(upload_to='images/', blank=True)
    slider_image_2 = models.ImageField(upload_to='images/', blank=True)
    slider_image_3 = models.ImageField(upload_to='images/', blank=True)
    slider_image_4 = models.ImageField(upload_to='images/', blank=True)
    slider_image_5 = models.ImageField(upload_to='images/', blank=True)

    @property
    def slider_images(self):
        fields = [field.name for field in self._meta.get_fields()]
        results = []
        for field in fields:
            if 'slider_image' in field:
                data = getattr(self, field)
                if data:
                    results.append(data.url)

        return results

    @property
    def slider_images(self): # simplified version
        results = [getattr(self, field.name) for field in self._meta.get_fields() 
        if 'slider_image' in field]
        return [result.url for result in results if result]

Now you can easily access this list in your templates:

{% for url in object.slider_images %}
  <img src="{{ url }}">
{% endfor %}

This is a bit out of scope for this question, but your slider_image fields looks like it should be a single ManyToManyField . Using a M2M here would massively simplify the amount of work you are doing, and would eliminate the need for my solution entirely. I can't really give you a solution using this because you will probably need to change several pieces of logic throughout your code before this will work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM