Вызывается для добавления в list_display, который ссылается на дополнительное поле в промежуточной модели отношения M2M - PullRequest
1 голос
/ 07 мая 2020

У меня есть две модели, Tender и Status, которые имеют отношение «многие ко многим» с промежуточной моделью TenderStatus. TenderStatus имеет дополнительное поле даты, которое обозначает дату применения каждого статуса. Я хочу показать все статусы для каждого тендера в list_display. Я понимаю, что мне нужно создать вызываемый объект в моем классе TenderAdmin для включения в list_display, и, хотя я могу перечислить статусы, у меня возникают проблемы с доступом к полю даты в промежуточной модели.

Вот сокращенная версия моего файла models.py :

class Tender(models.Model):
    name = models.CharField(
        max_length=255,
        null=False
    )
    tender_status = models.ManyToManyField(
        'Status',
        through='TenderStatus',
        related_name='tender_status'
    )

class Status(models.Model):
    status = models.CharField(
        max_length=50,
        null=False
    )

class TenderStatus(models.Model):
    tender = models.ForeignKey('Tender', on_delete=models.DO_NOTHING, blank=True, null=False)
    status = models.ForeignKey('Status', on_delete=models.DO_NOTHING, null=False)
    date = models.DateField(blank=True, null=False)

А вот сокращенный admin.py - обратите внимание на вызываемый status_list, он работает, но в нем нет даты. Все попытки, которые я сделал для доступа к дате, не сработали.

class TenderAdmin(admin.ModelAdmin, ExportCsvMixin):
    list_display = ['name', 'status_list']

    def status_list(self, obj):
        return [x.status for x in obj.tender_status.all()]
    status_list.allow_tags = True

Я пробовал это, но он не может найти дату и возвращает ошибку 500:

    def status_list(self, obj):
        return [str(x.date) + ': ' + x.status for x in obj.tender_status.all()]

Любая помощь в поиске правильного способа написания этой функции status_list, чтобы она обращалась к дате, была бы очень признательна!

1 Ответ

0 голосов
/ 07 мая 2020

Для всех, кто сталкивался с этим, я разобрался с ответом. Дополнительные поля для отношений «многие ко многим» описаны в документации , но не особенно подробно, и приведенный в них пример будет работать только для одного возвращаемого объекта (что - зачем вам вообще использовать M2M для что? во всяком случае). Суть в том, что вам нужно напрямую запросить модель-посредник, передав obj в качестве параметра фильтра. Вот созданный мной вызываемый объект, который работает:

    def status_list(self, obj):
        statuses = TenderStatus.objects.filter(tender=obj)
        return ', '.join([str(x.date) + ': ' + str(x.status) for x in statuses.all()])

Надеюсь, это поможет кому-то другому!

...