Last active
November 22, 2023 10:09
-
-
Save quxf2012/7c86333c886d2c3b7b002c3c3214f1d1 to your computer and use it in GitHub Desktop.
1. django admin export selected data to csv 2. django admin export data to csv without selected item;
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
from django.contrib import admin | |
@admin.register(models.XXXX) | |
class XxxxxAdmin(ExportQueryBaseWithoutSelect, admin.ModelAdmin): | |
serializer_class = XxxSerializer # | |
... | |
""" | |
from django.contrib import admin | |
from django.contrib.admin import helpers | |
from django.http import HttpRequest, FileResponse | |
from django.utils.timezone import now | |
from rest_framework.serializers import ModelSerializer | |
from rest_framework_csv.renderers import CSVStreamingRenderer | |
class ExportQueryBase: | |
""" | |
export_to_csv | |
1. 导出选择的数据; | |
2. 不支持无选择对象导出 | |
serializer_class | |
1. 需要在类中设置 serializer_class -> rest_framework.serializers | |
2. 如果没有设置, 使用rest_framework ModelSerializer 导出所有字段 | |
from rest_framework.serializers import ModelSerializer | |
""" | |
_actions = ["export_to_csv"] # 允许在admin后台不选择 item的情况下继续; | |
serializer_class = None | |
@staticmethod | |
def auto_model_serializer(model): | |
class Serializer(ModelSerializer): | |
class Meta: | |
model = None | |
fields = '__all__' | |
Serializer.Meta.model = model | |
return Serializer | |
@staticmethod | |
@admin.action(description="Export Selected or All", permissions=('export_xxxx',)) | |
def export_to_csv(model_admin: admin.ModelAdmin, request: HttpRequest, queryset): | |
model = model_admin.model | |
serializer_class = getattr(model_admin, 'serializer_class') or ExportQueryBase.auto_model_serializer(model) | |
c = serializer_class(queryset, many=True) | |
render_buffer = CSVStreamingRenderer().render(c.data, renderer_context={"bom": True, "encoding": "utf-8"}) | |
response = FileResponse(render_buffer, content_type="text/csv; charset=utf-8") | |
response['Content-Disposition'] = f'attachment; filename="{model._meta.db_table}_{now().strftime("%Y-%m-%d_%H_%M_%S")}.csv"' | |
return response | |
def get_actions(self, request): | |
actions = super().get_actions(request) | |
if 'export_to_csv' not in actions: | |
actions['export_to_csv'] = (ExportQueryBase.export_to_csv, "export_to_csv", ExportQueryBase.export_to_csv.short_description) | |
return actions | |
class ExportQueryBaseWithoutSelect(ExportQueryBase): | |
""" | |
1. 导出当前查询条件的所有数据, 无需选择对象; | |
2. 导出选择的数据; | |
""" | |
def get_params_queryset(self, request): | |
# 根据当前的query_params 生成 queryset | |
return self.get_changelist_instance(request).get_queryset(request) | |
def changelist_view(self, request, extra_context=None): | |
selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME) # 当前是否有选择对象 | |
if not selected: | |
try: | |
action_index = int(request.POST.get("index", 0)) | |
action = request.POST.getlist("action")[action_index] | |
if action in self._actions: | |
actions = self.get_actions(request) | |
# print(actions) | |
action_func = actions[action][0] | |
return action_func(self, request, self.get_params_queryset(request)) | |
except IndexError as e: | |
pass | |
return super().changelist_view(request, extra_context) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment