123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- from django.contrib import admin
- from django.apps import apps
- from import_export.admin import ImportExportModelAdmin, ImportExportMixin, ImportMixin
- from import_export.widgets import ManyToManyWidget
- from import_export import resources, fields
- import tablib
- from django_admin_search.admin import AdvancedSearchAdmin
- from .form import PolicyFormSearch
- from .models import Policy, DiseaseType
- # Set ordering of Apps and models in Django admin dashboard
- # https://stackoverflow.com/questions/58256151/set-ordering-of-apps-and-models-in-django-admin-dashboard
- ADMIN_ORDERING = (
- ('policies', ('Policy', 'MyPolicy', 'DiseaseType')),
- ('auth', ('User', 'Group')),
- ('admin_interface', ('Theme', ))
- )
- # see: https://cloud.tencent.com/developer/article/2219443
- # https://zhuanlan.zhihu.com/p/456360553
- # https://geek-docs.com/django/django-questions/776_django_parsing_fields_in_djangoimportexport_before_importing.html
- class PolicyResource(resources.ModelResource):
- # 给Resource添加一个自定义字段,指向模型的关系对象,用widget做格式规范
- # 关联关系的导入导出, ForeignKeyWidget, ManyToManyWidget
- disease_types = fields.Field(
- column_name='传染病类型',
- attribute='disease_types',
- widget=ManyToManyWidget(DiseaseType, separator=',', field='name')
- )
-
- def __init__(self, input_contract=None):
- super(PolicyResource, self).__init__()
- field_list = Policy._meta.fields
- self.verbose_name_dict = {}
- for i in field_list:
- self.verbose_name_dict[i.name] = i.verbose_name
-
- # def get_export_fields(self):
- # 默认导入导出field的column_name为字段的名称,这里修改为字段的verbose_name
- def get_fields(self): # 导入和导出的表头都需要用 verbose_name
- fields = super(PolicyResource, self).get_fields()
- for field in fields:
- field_name = self.get_field_name(field)
- # 如果有设置 verbose_name,则将 column_name 替换为 verbose_name, 否则维持原有的字段名。
- if field_name in self.verbose_name_dict.keys():
- field.column_name = self.verbose_name_dict[field_name]
- return fields
- def export(self, queryset=None, *args, **kwargs):
- """
- Exports a resource.
- """
- self.before_export(queryset, *args, **kwargs)
- if queryset is None:
- queryset = self.get_queryset()
- headers = self.get_export_headers()
- data = tablib.Dataset(headers=headers)
- for obj in self.iter_queryset(queryset):
- # obj.gender = obj.get_gender_display()
- data.append(self.export_resource(obj))
- self.after_export(queryset, data, *args, **kwargs)
- return data
- class Meta:
- skip_unchanged = True # 是否跳过的记录出现在导入结果对象
- report_skipped = False # 所有记录将被导入
- # export_order = ("id","传染病类型","政策类别","政策文件名","政策文件路径","文号","所属国家","发布部门","发布年份","发布日期","实施日期","关键词","时效性","效力级别","创建日期","更新日期","备注")
- export_order = ("id","disease_types", "category","file_name","number","country","department","year","publish_date","implementation_date","disease_types","keywords","timeliness","effectiveness_level","created_date","updated_date","comment")
- model = Policy
- verbose_name = True
- class MyPolicy(Policy):
- class Meta:
- proxy = True
- verbose_name = "政策批量导入导出"
- verbose_name_plural = "政策批量导入导出"
- class PolicyExportAdmin(ImportExportModelAdmin):
- list_display = ('file_name', 'id', 'category', 'year', 'department', 'publish_date', 'timeliness', 'effectiveness_level',)
- list_filter = ('category', 'year', 'department', 'disease_types', )
- def has_add_permission(self, request):
- return False
-
- def has_change_permission(self, request, obj=None):
- return False
- # get_queryset方法用于优化查询性能,通过select_related和prefetch_related方法提前加载关联的字段。
- def get_queryset(self, request):
- queryset = super().get_queryset(request)
- # queryset = queryset.select_related('category')
- queryset = queryset.prefetch_related('disease_types')
- return queryset
- # get_ordering方法用于指定默认的排序方式,这里按照publication_year字段进行排序。
- def get_ordering(self, request):
- return ['year']
- resource_class = PolicyResource
- class PolicyAdmin(AdvancedSearchAdmin):
- list_display = ('file_name', 'id', 'category', 'year', 'department', 'publish_date', 'timeliness', 'effectiveness_level',)
- list_filter = ('category', 'year', 'department', 'disease_types', )
- search_form = PolicyFormSearch
- # get_queryset方法用于优化查询性能,通过select_related和prefetch_related方法提前加载关联的字段。
- def get_queryset(self, request):
- queryset = super().get_queryset(request)
- # queryset = queryset.select_related('category')
- queryset = queryset.prefetch_related('disease_types')
- return queryset
- # get_ordering方法用于指定默认的排序方式,这里按照publication_year字段进行排序。
- def get_ordering(self, request):
- return ['year']
- # def changelist_view(self, request, extra_context=None):
- # # 自定义统计逻辑
- # # 根据发布年份、发布部门、政策类别、传染病类别和效力级别进行统计
- # # 实现你的统计逻辑
- # return super().changelist_view(request, extra_context=extra_context)
- admin.site.site_header = '中国传染病防治政策数据库'
- admin.site.site_title = '中国传染病防治政策数据库'
- admin.site.index_title = '中国传染病防治政策数据库'
- def get_app_list(self, request, app_label=None):
- """
- 应用、model 排序
- """
- app_dict = self._build_app_dict(request, app_label)
-
- if not app_dict:
- return
-
- NEW_ADMIN_ORDERING = []
- if app_label:
- for ao in ADMIN_ORDERING:
- if ao[0] == app_label:
- NEW_ADMIN_ORDERING.append(ao)
- break
-
- if not app_label:
- for app_key in list(app_dict.keys()):
- if not any(app_key in ao_app for ao_app in ADMIN_ORDERING):
- app_dict.pop(app_key)
-
- app_list = sorted(
- app_dict.values(),
- key=lambda x: [ao[0] for ao in ADMIN_ORDERING].index(x['app_label'])
- )
-
- for app, ao in zip(app_list, NEW_ADMIN_ORDERING or ADMIN_ORDERING):
- if app['app_label'] == ao[0]:
- for model in list(app['models']):
- if not model['object_name'] in ao[1]:
- app['models'].remove(model)
- app['models'].sort(key=lambda x: ao[1].index(x['object_name']))
- return app_list
- # 模块排序
- admin.AdminSite.get_app_list = get_app_list
- # 应用名设置成中文
- # https://docs.djangoproject.com/en/4.1/ref/applications/#for-application-authors
- apps.get_app_config('auth').verbose_name = "系统管理权限"
- apps.get_app_config('admin_interface').verbose_name = "界面管理"
- admin.site.register(Policy, PolicyAdmin)
- admin.site.register(MyPolicy, PolicyExportAdmin)
- admin.site.register(DiseaseType)
|