Статическая переменная модели, определяющая, какие поля модели отображаются в ListView
Я пытаюсь сделать общее представление ListView, которое может быть заполнено подключенной к нему моделью. Поэтому я вставил несколько статических переменных в мою модель, которые используются для заполнения представления. Они находятся в нижней части определения модели.
class AssignmentAd(models.Model):
class StatChoices(models.TextChoices):
REGISTERED = "Registered"
PENDING = "Pending"
CANCELED = "Canceled"
class FieldChoices(models.TextChoices):
JFS = "JFS"
JAVA = "Java"
CLOUD = "Cloud"
# id = models.CharField(max_length=20)
# contact_person = models.ForeignKey(Question, on_delete=models.CASCADE)
status = models.CharField(max_length=20, choices=StatChoices.choices, default=StatChoices.PENDING)
# period = models.DateTimeField('period')
# broker
deadline = models.DateField('Deadline')
field = models.CharField(max_length=20, choices=FieldChoices.choices, default=FieldChoices.JFS)
location = models.CharField(max_length=40)
remote = models.IntegerField(
default=0,
validators=[
MaxValueValidator(100),
MinValueValidator(0)
]
)
# status_reason
# url
title = models.CharField(max_length=200)
REQUIRED_FIELDS = ['status', 'period', 'title']
# These static values are used to populate the ListView template
LIST_HEADLINE = 'assignment ads'
SINGLE_ITEM = 'assignment ad'
LIST_COLTITLES = ['title', 'field', 'status', 'deadline', 'remote', 'location']
LIST_COLDATA = [title, field, status, deadline, remote, location]
У меня заголовки столбцов списка заполняются путем чтения поля LIST_COLTITLES, но я не могу прочитать данные столбцов для каждого объекта. Вот мой шаблон и то, как я пытался сделать это, читая LIST_COLDATA.
В представлении я импортирую все в контекст следующим образом:
class TrackAssignmentAds(generic.ListView):
model = AssignmentAd
template_name = 'track/assignment_ads.html'
context_object_name = 'model_objs'
paginate_by = 5
def get_context_data(self, **kwargs):
context = super(TrackAssignmentAds, self).get_context_data(**kwargs)
context['currentpage'] = 'assignment_ads'
context['listheadline'] = TrackAssignmentAds.model.LIST_HEADLINE
context['listsingleitem'] = TrackAssignmentAds.model.SINGLE_ITEM
context['listcoltitles'] = TrackAssignmentAds.model.LIST_COLTITLES
context['listcoldata'] = TrackAssignmentAds.model.LIST_COLDATA
context['model_form'] = AssignmentAdForm()
return context
def post(self, request, *args, **kwargs):
form = AssignmentAdForm(request.POST)
if form.is_valid():
form.save()
else:
messages.success(request, "Invalid form")
return redirect('assignment_ads')
Затем я использую эти значения из контекста в шаблоне.
Извините за хаос вышеприведенного HTML. Часть, которая не работает:
{% for ad in model_objs %}
{% for data in listcoldata %}
<td class="border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap p-4">
{{ ad.data }}
</td>
{% endfor %}
{% endfor %}
Мне нужно извлечь поля объектов модели, которые определены в статической переменной LIST_COLDATA, и вставить их выше места {{ ad.data }} итеративно.
Мне пришлось сделать пользовательский тег https://docs.djangoproject.com/en/4.1/howto/custom-template-tags/
Подобно этому:
from django import template
def getattribute(value, arg):
"""Returns a model object's field value based on string name arg"""
if hasattr(value, str(arg)):
return getattr(value, arg)
register = template.Library()
register.filter('getattribute', getattribute)
А затем используйте его в HTML-шаблоне следующим образом:
{% for ad in model_objs %}
{% for data in ad.LIST_COLDATA %}
{{ ad|getattribute:data }}
{% endfor %}
{% endfor %}
Где данные представляют собой LIST_COLDATA - это список строк, указывающих, какие поля должны заполнять столбцы списка. Пользовательский тег помогает извлечь конкретное поле путем чтения строк из списка.