添加一个按钮以导出到 Wagtail 仪表板上的 csv/xlsx 文件

Adding a button to export to a csv/xlsx file on Wagtail Dashboard

我正在尝试此堆栈溢出 post () 中提到的解决方案,但该解决方案可能已过时,或者至少它对我不起作用,我不确定为什么.

目标:能够将对象的数据导出到 csv

首先,必须稍微调整按钮 HTML 代码以使其格式正确,如下所示:

{% extends "modeladmin/index.html" %}
{% block header_extra %}
    <div class="right">
        <div class="addbutton" style="margin-left: 2em;">
            {% include "modeladmin/includes/button.html" with button=view.button_helper.export_button %}
            <a href="#" class="button bicolor icon icon-download">My button</a>
        </div>
    </div>
    {{ block.super }}{% comment %}Display the original buttons {% endcomment %}
{% endblock %}

然后我复制并粘贴了视图和辅助函数:

from django.contrib.auth.decorators import login_required
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.utils.functional import cached_property
from django.utils.translation import ugettext as _
from wagtail.contrib.modeladmin.helpers import AdminURLHelper, ButtonHelper
from wagtail.contrib.modeladmin.views import IndexView


class ExportButtonHelper(ButtonHelper):
    """
    This helper constructs all the necessary attributes to create a button.
    
    There is a lot of boilerplate just for the classnames to be right :(
    """
    
    export_button_classnames = ['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)
        text = _('Export {}'.format(self.verbose_name_plural.title()))

        return {
            'url': self.url_helper.get_action_url('export', query_params=self.request.GET),
            'label': text,
            'classname': cn,
            'title': text,
        }


class ExportAdminURLHelper(AdminURLHelper):
    """
    This helper constructs the different urls.
    
    This is mostly just to overwrite the default behaviour
    which consider any action other than 'create', 'choose_parent' and 'index'
    as `object specific` and will try to add the object PK to the url
    which is not what we want for the `export` option.
    
    In addition, it appends the filters to the action.
    """

    non_object_specific_actions = ('create', 'choose_parent', 'index', 'export')

    def get_action_url(self, action, *args, **kwargs):
        query_params = kwargs.pop('query_params', None)

        url_name = self.get_action_url_name(action)
        if action in self.non_object_specific_actions:
            url = reverse(url_name)
        else:
            url = reverse(url_name, args=args, kwargs=kwargs)

        if query_params:
            url += '?{params}'.format(params=query_params.urlencode())

        return url

    def get_action_url_pattern(self, action):
        if action in self.non_object_specific_actions:
            return self._get_action_url_pattern(action)

        return self._get_object_specific_action_url_pattern(action)
        

class ExportView(IndexView):
    """
    A Class Based View which will generate 
    """
    
    def export_csv(self):
        data = self.queryset.all()
        response = ...
        return response
    
    
    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
        super().dispatch(request, *args, **kwargs)
        return self.export_csv()

        
class ExportModelAdminMixin(object):
    """
    A mixin to add to your model admin which hooks the different helpers, the view
    and register the new urls.
    """

    button_helper_class = ExportButtonHelper
    url_helper_class = ExportAdminURLHelper

    export_view_class = ExportView

    def get_admin_urls_for_registration(self):
        urls = super().get_admin_urls_for_registration()
        urls += (
            url(
                self.url_helper.get_action_url_pattern('export'),
                self.export_view,
                name=self.url_helper.get_action_url_name('export')
            ),
        )

        return urls

    def export_view(self, request):
        kwargs = {'model_admin': self}
        view_class = self.export_view_class
        return view_class.as_view(**kwargs)(request)

然后我将 ModelAdmin 添加到挂钩中。我能够看到该按钮,但它无法正常工作(导出 csv)。事实上,它什么也没做(毕竟 href 是 #),我觉得我错过了一些步骤。

我使用了与您相同的实现方式。 我猜你在 def export_csv(self) 方法中遇到了问题 这是我的实现

from djqscsv.djqscsv import render_to_csv_response


class ExportView(IndexView):
    model_admin = None

    def export_csv(self) -> dict:
        if (self.model_admin is None) or not hasattr(
            self.model_admin, "csv_export_fields"
        ):
            data = self.queryset.all().values()
        else:
            data = self.queryset.all().values(*self.model_admin.csv_export_fields)
        return render_to_csv_response(data)

    @method_decorator(login_required)
    def dispatch(self, request: HttpRequest, *args: list, **kwargs: dict) -> dict:
        super().dispatch(request, *args, **kwargs)
        return self.export_csv()

csv_export_fields 可以添加到您的模型管理员以指定要导出的字段

我在这里添加 HTML 文件:

{% extends "modeladmin/index.html" %}

{% block header_extra %}
    {% include 'modeladmin/includes/button.html' with button=view.button_helper.export_button %}
    {{ block.super }}
{% endblock %}

你的admin.py

class MyModelAdmin(ModelAdmin, ExportModelAdminMixin): 
    model = MyModel 
    menu_icon = 'tag' 
    menu_order = 200 
    index_template_name = "wagtailadmin/export_csv.html"
    csv_export_fields = [ "field_name","field_name_1", ]
    list_display = ('first_name', 'last_name'') 
    search_fields = ('first_name', 'last_name',)