forked from quant-speed-AI/Scoring-System
创赢未来评分系统 - 初始化提交(移除大文件)
This commit is contained in:
149
backend/community/admin_actions.py
Normal file
149
backend/community/admin_actions.py
Normal file
@@ -0,0 +1,149 @@
|
||||
import csv
|
||||
import json
|
||||
import datetime
|
||||
from django.http import HttpResponse
|
||||
from django.utils.encoding import escape_uri_path
|
||||
|
||||
def flatten_json(y):
|
||||
"""
|
||||
Flatten a nested json object
|
||||
"""
|
||||
out = {}
|
||||
|
||||
def flatten(x, name=''):
|
||||
if type(x) is dict:
|
||||
for a in x:
|
||||
flatten(x[a], name + a + '_')
|
||||
elif type(x) is list:
|
||||
i = 0
|
||||
for a in x:
|
||||
flatten(a, name + str(i) + '_')
|
||||
i += 1
|
||||
else:
|
||||
out[name[:-1]] = x
|
||||
|
||||
flatten(y)
|
||||
return out
|
||||
|
||||
def get_signup_info_keys(queryset):
|
||||
"""
|
||||
Collect all unique keys from the signup_info JSON across the queryset
|
||||
"""
|
||||
keys = set()
|
||||
for obj in queryset:
|
||||
if obj.signup_info and isinstance(obj.signup_info, dict):
|
||||
# Flatten the dictionary first to get all nested keys
|
||||
flat_info = flatten_json(obj.signup_info)
|
||||
keys.update(flat_info.keys())
|
||||
return sorted(list(keys))
|
||||
|
||||
def export_signups_csv(modeladmin, request, queryset):
|
||||
"""
|
||||
Export selected signups to CSV, including flattened JSON fields
|
||||
"""
|
||||
opts = modeladmin.model._meta
|
||||
filename = f"{opts.verbose_name}_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
|
||||
|
||||
response = HttpResponse(content_type='text/csv; charset=utf-8-sig')
|
||||
response['Content-Disposition'] = f'attachment; filename={escape_uri_path(filename)}'
|
||||
|
||||
writer = csv.writer(response)
|
||||
|
||||
# Base fields to export
|
||||
base_headers = ['ID', '活动标题', '用户昵称', '用户ID', '报名时间', '状态', '关联订单ID']
|
||||
|
||||
# Get dynamic JSON keys
|
||||
json_keys = get_signup_info_keys(queryset)
|
||||
|
||||
# Write header
|
||||
writer.writerow(base_headers + json_keys)
|
||||
|
||||
# Write data
|
||||
for obj in queryset:
|
||||
row = [
|
||||
str(obj.id),
|
||||
obj.activity.title,
|
||||
obj.user.nickname if obj.user else 'Unknown',
|
||||
str(obj.user.id) if obj.user else '',
|
||||
obj.signup_time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
obj.get_status_display(),
|
||||
str(obj.order.id) if obj.order else ''
|
||||
]
|
||||
|
||||
# Add JSON data
|
||||
flat_info = {}
|
||||
if obj.signup_info and isinstance(obj.signup_info, dict):
|
||||
flat_info = flatten_json(obj.signup_info)
|
||||
|
||||
for key in json_keys:
|
||||
val = flat_info.get(key, '')
|
||||
if val is None:
|
||||
val = ''
|
||||
row.append(str(val))
|
||||
|
||||
writer.writerow(row)
|
||||
|
||||
return response
|
||||
|
||||
export_signups_csv.short_description = "导出选中报名记录为 CSV (含详细信息)"
|
||||
|
||||
def export_signups_excel(modeladmin, request, queryset):
|
||||
"""
|
||||
Export selected signups to Excel, including flattened JSON fields
|
||||
"""
|
||||
try:
|
||||
from openpyxl import Workbook
|
||||
except ImportError:
|
||||
modeladmin.message_user(request, "请先安装 openpyxl 库以使用 Excel 导出功能", level='error')
|
||||
return
|
||||
|
||||
opts = modeladmin.model._meta
|
||||
filename = f"{opts.verbose_name}_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
|
||||
|
||||
response = HttpResponse(
|
||||
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
)
|
||||
response['Content-Disposition'] = f'attachment; filename={escape_uri_path(filename)}'
|
||||
|
||||
wb = Workbook()
|
||||
ws = wb.active
|
||||
ws.title = str(opts.verbose_name)[:31] # Sheet name limit is 31 chars
|
||||
|
||||
# Base fields to export
|
||||
base_headers = ['ID', '活动标题', '用户昵称', '用户ID', '报名时间', '状态', '关联订单ID']
|
||||
|
||||
# Get dynamic JSON keys
|
||||
json_keys = get_signup_info_keys(queryset)
|
||||
|
||||
# Write header
|
||||
ws.append(base_headers + json_keys)
|
||||
|
||||
# Write data
|
||||
for obj in queryset:
|
||||
row = [
|
||||
obj.id,
|
||||
obj.activity.title,
|
||||
obj.user.nickname if obj.user else 'Unknown',
|
||||
obj.user.id if obj.user else '',
|
||||
obj.signup_time.replace(tzinfo=None) if obj.signup_time else '', # Remove tz for Excel
|
||||
obj.get_status_display(),
|
||||
obj.order.id if obj.order else ''
|
||||
]
|
||||
|
||||
# Add JSON data
|
||||
flat_info = {}
|
||||
if obj.signup_info and isinstance(obj.signup_info, dict):
|
||||
flat_info = flatten_json(obj.signup_info)
|
||||
|
||||
for key in json_keys:
|
||||
val = flat_info.get(key, '')
|
||||
if val is None:
|
||||
val = ''
|
||||
row.append(str(val)) # Ensure string for simplicity, or handle types
|
||||
|
||||
ws.append(row)
|
||||
|
||||
wb.save(response)
|
||||
return response
|
||||
|
||||
export_signups_excel.short_description = "导出选中报名记录为 Excel (含详细信息)"
|
||||
Reference in New Issue
Block a user