在 django admin 中将所有 list_display 字段导出到 csv

Har*_*eno 5 django django-admin

我正在使用https://books.agiliq.com/projects/django-admin-cookbook/en/latest/export.html上的食谱

class ExportCsvMixin:
    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)
        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"
Run Code Online (Sandbox Code Playgroud)

效果很好,只是它不会导出我在管理面板中看到的所有列。我添加了一些像这样的额外列

class MeetingAdmin(admin.ModelAdmin, ExportCsvMixin):
    actions = ["export_as_csv"]
    list_display = (
        "__str__",
        "expert_network",
    )

    def expert_network(self, obj):
        if obj.expert:
            return obj.expert.network.name
        else:
            return "-"
Run Code Online (Sandbox Code Playgroud)

是否可以改进 ExportCsvMixin 以导出可调用的 list_display 字段?

我目前正在尝试循环 list_display 但我不知道如何使用可调用对象

class ExportCsvMixin:
    def export_as_csv(self, request, queryset):
        meta = self.model._meta
        # field_names = [field.name for field in meta.fields]
        field_names = list(self.list_display)

        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:
            result = []
            for field in field_names:
                attr = getattr(obj, field)
                if callable(attr):
                    result.append(attr())
                else:
                    result.append(attr)
            row = writer.writerow(result)

        return response

    export_as_csv.short_description = "Export Selected"
Run Code Online (Sandbox Code Playgroud)

Har*_*eno 6

想出了这个

class ExportCsvMixin:
    def export_as_csv(self, request, queryset):
        meta = self.model._meta
        # field_names = [field.name for field in meta.fields]
        field_names = list(self.list_display)

        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:
            result = []
            for field in field_names:
                attr = getattr(obj, field, None)
                if attr and callable(attr):
                    result.append(attr())
                elif attr:
                    result.append(attr)
                else:
                    attr = getattr(self, field, None)
                    if attr:
                        result.append(attr(obj))
                    else:
                        result.append(attr)
            row = writer.writerow(result)

        return response

    export_as_csv.short_description = "Export Selected"
Run Code Online (Sandbox Code Playgroud)

基本上,我们在对象上查找属性或可调用对象,如果不存在,则我们查看 modelAdmin 并使用对象作为参数调用可调用对象。