Django. Как вывести в шаблон html только те поля FileField, которые хранят файл?
Есть модель с 14ю полями FileField (все поля blank=True). Файлы через эти поля будут переданы только через админку.
models.py (... - использовал для сокращения модели)
from django.db import models
class Project(models.Model):
location = models.CharField(max_length=150, help_text="Ориентир (локация)", verbose_name="Где находится")
slug = models.SlugField(max_length=150, unique=True, help_text="Ссылка страницы объекта (генерируется автоматически)", verbose_name="Ссылка на страницу")
ready = models.BooleanField(default=False, help_text="Дом сдан или нет? (по умолчанию не сдан)", verbose_name="Готовность объекта")
ds_contract = models.FileField(default="", upload_to ='project_docs/%Y/%m/%d/', help_text="Загрузите файл", verbose_name="Договор участия в долевом строительстве", blank=True)
project_dec = models.FileField(default="", upload_to ='project_docs/%Y/%m/%d/', help_text="Загрузите файл", verbose_name="Форма проектной декларации", blank=True)
...
gen_plan = models.FileField(default="", upload_to ='project_docs/%Y/%m/%d/', help_text="Загрузите файл", verbose_name="Генеральный план", blank=True)
class Meta:
verbose_name = "Проект"
verbose_name_plural = "Проекты"
def __str__(self):
return self.location
views.py
from django.shortcuts import render
from .models import Project
def get_project(request, slug):
projects = Project.objects.all()
return render(request, 'main/project.html', {"projects": projects})
Дело в том, что не всегда будут использованы все 14 полей FileField. Как сделать так, чтобы вывести в шаблон только те поля FileFiled, через которые были переданы файлы? А те поля, что не были использованы, не выводить в шаблоне. Второй вопрос. Как для upload_to генерировать папку исходя из переданного значения для поля location? Заранее благодарю!
Update:
Добавляю template ():
{% block content %}
<h2>Тут будет новый строящийся объект</h2>
{% for project in projects %}
{% for file in project.get_file_fields %}
{% if file.field %}
{{ file.label }}: <a href="../../media/{{ file.field }}" target="_blank">Скачать</a><br>
{% endif %}
{% endfor %}
{% endfor %}
{% endblock %}
views.py
def get_project(request, slug):
projects = Project.objects.all()
return render(request, 'main/project.html', {"projects": projects})
Ответы (1 шт):
- что бы вывести только те поля FileField, в которых есть значения можно добавить в модель следующий метод, который будет выдавать список полей с названиями
def get_file_fields(self):
return [{"label": field.verbose_name, "field": getattr(self, field.name)} for field in self._meta.get_fields()
if isinstance(field, models.FileField)]
и затем в шаблоне проверять есть ли значение в этом поле, и если есть, выводить его
{% for file in obj.get_file_fields %}
{% if file.field %}
{{ file.label }}: {{ file.field}}
{% endif %}
{% endfor %}
где obj это экземпляр модели
- что бы путь зависел от значения другого поля
def get_upload_dir(instance, file_name):
return "{}/{}".format(slugify(instance.location), file_name)
class Project(models.Model):
...
ds_contract = models.FileField(default="", upload_to=get_upload_dir, help_text="Загрузите файл", verbose_name="Договор участия в долевом строительстве", blank=True)
...
вместо slugify(instance.location) укажи собственное правило, которое в зависимости от location возвращает нужную папку