Python / Django / Jinja2: Как расширить имя переменной значением другой переменной (например, в цикле for)? - PullRequest
1 голос
/ 09 октября 2019

В моей модели django дБ у меня есть, например, 5x ImageField, которую я хочу использовать для карусели в передней части:

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)

В зависимости от того, были загружены изображения или нет, яхочу отобразить изображения, и я ищу подход, похожий на что-то вроде этого:

{% 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 %}

Возможно ли нечто подобное? Какие другие хорошие подходы для этой проблемы?

1 Ответ

1 голос
/ 10 октября 2019

Рекомендуемый подход для сложной логики в шаблонах состоит в том, чтобы записывать логику в методе модели, а не в самом шаблоне.

В вашем случае, я думаю, это то, что вы хотите:

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]

Теперь вы можете легко получить доступ к этому списку в своих шаблонах:

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

Это немного выходит за рамки этого вопроса, но ваши поля slider_image выглядят так, как будто они должны быть одиночными ManyToManyField. Использование M2M в данном случае значительно упростит объем выполняемой вами работы и полностью устранит необходимость в моем решении. Я не могу дать вам решение, используя это, потому что вам, вероятно, придется изменить несколько частей логики в вашем коде, прежде чем это сработает.

...