繁体   English   中英

如何将 django 管理更改列表导出为 csv

[英]How to export django admin changelist as csv

我想将我的更改列表list_display字段)导出为 csv。 我使用了https://books.agiliq.com/projects/django-admin-cookbook/en/latest/export.html 中的代码,但它为模型字段创建了 csv。 但就我而言,我想将更改列表导出为 csv,而不是模型字段。 另请注意,changelist( list_display ) 中的大多数字段都是 Admin 中的计算字段。

这是我的代码

class ExportCsvMixin:

    def export_as_csv(self, request, queryset):

        meta = queryset.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)
        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"


class MyAdmin(admin.ModelAdmin, ExportCsvMixin):
    list_display = ('field1',
                    'field2'
           )
    list_filter = ('field2')
    actions = ["export_as_csv"]

    def field1(self, obj):
        <return logic here>

    def field2(self, obj):
        <return logic here>

笔记:

  1. field1 和 field2 是计算字段,而不是模型字段。
  2. 我的模型是代理模型。 但我认为在这种情况下不会有任何区别。

我希望 csv 只包含field1field2数据,因为它们在我的更改列表中。 可能的诀窍是以某种方式将查询集指向更改列表的查询集。 但是怎么办呢? 或者,如果有人可以建议其他解决方案甚至 api 来实现这一目标?

我有同样的问题,我设法以这种方式破解它。

  • 我查看了 ModelAdmin 基类,发现了负责处理操作方法的函数,它称为response_action ,我查看了它并更改了它返回我需要的查询集。

假设您有一个返回“field1”和“field2”的查询集。

以下是我如何编辑函数以返回自定义查询集:

def response_action(self, request, queryset):
        """
        Handle an admin action. This is called if a request is POSTed to the
        changelist; it returns an HttpResponse if the action was handled, and
        None otherwise.
        """

        # There can be multiple action forms on the page (at the top
        # and bottom of the change list, for example). Get the action
        # whose button was pushed.
        try:
            action_index = int(request.POST.get('index', 0))
        except ValueError:
            action_index = 0

        # Construct the action form.
        data = request.POST.copy()
        data.pop(admin.helpers.ACTION_CHECKBOX_NAME, None)
        data.pop("index", None)

        # Use the action whose button was pushed
        try:
            data.update({'action': data.getlist('action')[action_index]})
        except IndexError:
            # If we didn't get an action from the chosen form that's invalid
            # POST data, so by deleting action it'll fail the validation check
            # below. So no need to do anything here
            pass

        action_form = self.action_form(data, auto_id=None)
        action_form.fields['action'].choices = self.get_action_choices(request)

        # If the form's valid we can handle the action.
        if action_form.is_valid():
            action = action_form.cleaned_data['action']
            select_across = action_form.cleaned_data['select_across']
            func = self.get_actions(request)[action][0]

            # Get the list of selected PKs. If nothing's selected, we can't
            # perform an action on it, so bail. Except we want to perform
            # the action explicitly on all objects.
            selected = request.POST.getlist(admin.helpers.ACTION_CHECKBOX_NAME)
            if not selected and not select_across:
                # Reminder that something needs to be selected or nothing will
                # happen
                msg = _("Items must be selected in order to perform "
                        "actions on them. No items have been changed.")
                self.message_user(request, msg, messages.WARNING)
                return None

            if not select_across:
                ##### change this line with your queryset that return field one and two
                queryset = 'your_queryset_with_field'

            response = func(self, request, queryset)

            # Actions may return an HttpResponse-like object, which will be
            # used as the response from the POST. If not, we'll be a good
            # little HTTP citizen and redirect back to the changelist page.
            if isinstance(response, HttpResponseBase):
                return response
            else:
                return HttpResponseRedirect(request.get_full_path())
        else:
            msg = _("No action selected.")
            self.message_user(request, msg, messages.WARNING)
            return None

在这个函数中检查我命令的部分#####在继承自模型管理类的类中重新定义该函数

该函数返回一个自定义查询集,现在您可以根据它编辑您的 export_as_csv_function。

def export_as_csv(self, request, queryset):

        field_names = ["field_one", "field_two"]

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

        writer.writerow(field_names)
        for obj in queryset:
            writer.writerow([obj.get(field) for field in field_names])

        return response

它和你可以去下载你的 CSV 与海关字段。

我希望现在还为时不晚,这可以帮助其他有同样问题的人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM