首页 > 解决方案 > 如何集成 Django Import Export 和 Wagtail?

问题描述

我正在尝试将 django-import-export 中的模型资源添加到 Wagtail 的管理员中。我能找到的唯一文档说你会通过钩子来做。问题是,我不断收到错误消息:

missing 2 required positional arguments: 'model' and 'admin_site'

整体resourceModelAdmin是:

class AccountResource(resources.ModelResource):

    class Meta:
        model = Account
        fields = ('first_name', 'last_name', 'email', 'created', 'archived')

class AccountsAdmin(ImportExportModelAdmin, ModelAdmin):
    resource_class = AccountResource
    model = Account
    menu_label = 'Accounts'  # ditch this to use verbose_name_plural from model
    menu_icon = 'group'  # change as required
    menu_order = 200  # will put in 3rd place (000 being 1st, 100 2nd)
    add_to_settings_menu = False  # or True to add your model to the Settings sub-menu
    exclude_from_explorer = False # or True to exclude pages of this type from Wagtail's explorer view
    list_display = ('first_name', 'last_name', 'email', 'created', 'archived')
    search_fields = ('first_name', 'last_name', 'email', 'created')

# Now you just need to register your customised ModelAdmin class with Wagtail
modeladmin_register(AccountsAdmin)

有什么建议么?

标签: djangodjango-adminwagtaildjango-import-export

解决方案


WagtailModelAdmin不共享 Django 的 API ModelAdmin

来自 django-import-export 的 mixin 期望与 Django 一起使用,ModelAdmin并且不会与 Wagtail 一起使用,ModelAdmin因为您已经亲身体验过。

对于导出功能,我通过将export_actionDjangoModelAdmin的 与ExportMixinWagtail 的 url挂钩来解决了这个问题ModelAdmin

这可能不太漂亮,但允许重用视图和属于ExportMixin.

在 GitHub 上发布了一个使用这种设计的示例项目。

可以在这里找到的实际胶水代码并没有那么多:

from django.conf.urls import url
from django.contrib.admin import ModelAdmin as DjangoModelAdmin
from django.core.exceptions import ImproperlyConfigured
from django.utils.http import urlencode
from django.utils.translation import gettext_lazy as _
from import_export.admin import ExportMixin
from wagtail.contrib.modeladmin.helpers import ButtonHelper


class ExporterDummySite:
    name = None

    def each_context(self, request):
        return {}


class WMAExporter(ExportMixin, DjangoModelAdmin):
    export_template_name = 'wma_export/export.html'

    def __init__(self, wagtail_model_admin):
        self.wagtail_model_admin = wagtail_model_admin
        super().__init__(wagtail_model_admin.model, ExporterDummySite())

    def get_export_queryset(self, request):
        index_view = self.wagtail_model_admin.index_view_class(
            model_admin=self.wagtail_model_admin
        )
        index_view.dispatch(request)
        return index_view.get_queryset(request)


class ExportButtonHelper(ButtonHelper):
    export_button_classnames = ['bicolor', 'icon', 'icon-download']

    def export_button(self, classnames_add=None, classnames_exclude=None):
        if classnames_add is None:
            classnames_add = []
        if classnames_exclude is None:
            classnames_exclude = []
        classnames = self.export_button_classnames + classnames_add
        cn = self.finalise_classname(classnames, classnames_exclude)
        return {
            'url': self.url_helper.get_action_url("export") + '?' + urlencode(self.view.params),
            'label': _('Export'),
            'classname': cn,
            'title': _('Export these %s') % self.verbose_name_plural,
        }


class WMAExportMixin:
    button_helper_class = ExportButtonHelper
    exporter_class = None

    def get_admin_urls_for_registration(self):
        return super().get_admin_urls_for_registration() + (
            url(self.url_helper._get_action_url_pattern("export"),
                self.export_view,
                name=self.url_helper.get_action_url_name("export")),
        )

    def export_view(self, request):
        if self.exporter_class is None:
            raise ImproperlyConfigured(f"{self.__class__.__name__}.exporter_class not set!")
        exporter = self.exporter_class(self)
        return exporter.export_action(request)

我会假设可以做类似的事情来实现导入部分。


推荐阅读