Статическая переменная модели, определяющая, какие поля модели отображаются в 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 - это список строк, указывающих, какие поля должны заполнять столбцы списка. Пользовательский тег помогает извлечь конкретное поле путем чтения строк из списка.

Вернуться на верх