Пользовательский декоратор для Django admin.ModelAdmin для добавления действий

Я пытаюсь создать функцию "экспорт модели в csv в панели администратора" и добавить ее к actions в admin.ModelAdmin. Выбрав несколько строк в таблице в панели администратора, цель состоит в том, чтобы экспортировать выбранные строки в csv. Однако мой текущий код в decorators.py::exportable_model не достиг моей цели.

Версии:

  • Python: 3.10
  • Django: 4.0.4

mixins.py

import csv
import codecs
from django.http import HttpResponse


class ExportCsvMixin:
    # ref: https://books.agiliq.com/projects/django-admin-cookbook/en/latest/export.html

    def export_as_csv(self, request, queryset):

        meta = self.model._meta
        field_names = [field.name for field in meta.fields]

        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)

        # To export CN characters. Ref: https://stackoverflow.com/a/63242835/16450509
        response.write(codecs.BOM_UTF8)

        writer = csv.writer(response)

        writer.writerow(field_names)
        for obj in queryset:
            row = writer.writerow([getattr(obj, field) for field in field_names])

        return response

    export_as_csv.short_description = "Export Selected (.csv)"

admin.py

@exportable_model(export_format="csv")
@admin.register(ParticipantType)
class ParticipantTypeAdmin(admin.ModelAdmin, ExportCsvMixin):
    list_display = [field.name for field in ParticipantType._meta.get_fields()]


@exportable_model(export_format="csv")
@admin.register(PropsEventType)
class PropsEventTypeAdmin(admin.ModelAdmin, ExportCsvMixin):
    list_display = [field.name for field in PropsEventType._meta.get_fields()]


@exportable_model(export_format="csv")
@admin.register(LimitedTimeEventType)
class LimitedTimeEventTypeAdmin(admin.ModelAdmin, ExportCsvMixin):
    list_display = [field.name for field in LimitedTimeEventType._meta.get_fields()]

Тенденция decorators.py, которая ссылается на стиль кодирования в register функции в @admin.register (from django.contrib import admin):

def exportable_model(export_format: str):
    from django.contrib.admin import ModelAdmin
    from .mixins import ExportCsvMixin

    def _decorator(admin_class):
        if not issubclass(admin_class, ModelAdmin):
            raise ValueError("Wrapped class must subclass ModelAdmin.")

        actions = admin_class.actions

        if export_format == "csv" and issubclass(admin_class, ExportCsvMixin):
            # I tried to append the action instead of overwriting the existing actions,
            # but this code gives me errors.
            actions.append("export_as_csv")
            admin_class.actions = actions

        return admin_class

    return _decorator

Когда я запускаю Django с помощью python manage.py runserver, приложение выдает следующие ошибки:

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "C:\Program Files\Python310\lib\threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "C:\Program Files\Python310\lib\threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Projects\py\kab-event-calendar-py\venv\lib\site-packages\django\utils\autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "C:\Projects\py\kab-event-calendar-py\venv\lib\site-packages\django\core\management\commands\runserver.py", line 134, in inner_run
    self.check(display_num_errors=True)
  File "C:\Projects\py\kab-event-calendar-py\venv\lib\site-packages\django\core\management\base.py", line 558, in check
    raise SystemCheckError(msg)
django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:

ERRORS:
<class 'enums.admin.LimitedTimeEventTypeAdmin'>: (admin.E130) __name__ attributes of actions defined in LimitedTimeEventTypeAdmin must be unique. Name 'export_as_csv' is not unique.
<class 'enums.admin.ParticipantTypeAdmin'>: (admin.E130) __name__ attributes of actions defined in ParticipantTypeAdmin must be unique. Name 'export_as_csv' is not unique.
<class 'enums.admin.PropsEventTypeAdmin'>: (admin.E130) __name__ attributes of actions defined in PropsEventTypeAdmin must be unique. Name 'export_as_csv' is not unique.

System check identified 3 issues (0 silenced).

Если я правильно понимаю, эта ошибка выглядит так, как будто декорированные подклассы admin.ModelAdmin повторно используют actions в классах-сестрах, что-то вроде

@admin.register(ParticipantType)
class ParticipantTypeAdmin(admin.ModelAdmin, ExportCsvMixin):
    list_display = [field.name for field in ParticipantType._meta.get_fields()]
    actions = ["export_as_csv"]


@admin.register(PropsEventType)
class PropsEventTypeAdmin(admin.ModelAdmin, ExportCsvMixin):
    list_display = [field.name for field in PropsEventType._meta.get_fields()]
    actions = ["export_as_csv", "export_as_csv"]


@admin.register(LimitedTimeEventType)
class LimitedTimeEventTypeAdmin(admin.ModelAdmin, ExportCsvMixin):
    list_display = [field.name for field in LimitedTimeEventType._meta.get_fields()]
    actions = ["export_as_csv", "export_as_csv", "export_as_csv"]

Как исправить функцию exportable_model?

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