admin.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. from django.contrib import admin
  2. from django.apps import apps
  3. from import_export.admin import ImportExportModelAdmin, ImportExportMixin, ImportMixin
  4. from import_export.widgets import ManyToManyWidget
  5. from import_export import resources, fields
  6. import tablib
  7. from django_admin_search.admin import AdvancedSearchAdmin
  8. from .form import PolicyFormSearch
  9. from .models import Policy, DiseaseType
  10. # Set ordering of Apps and models in Django admin dashboard
  11. # https://stackoverflow.com/questions/58256151/set-ordering-of-apps-and-models-in-django-admin-dashboard
  12. ADMIN_ORDERING = (
  13. ('policies', ('Policy', 'MyPolicy', 'DiseaseType')),
  14. ('auth', ('User', 'Group')),
  15. ('admin_interface', ('Theme', ))
  16. )
  17. # see: https://cloud.tencent.com/developer/article/2219443
  18. # https://zhuanlan.zhihu.com/p/456360553
  19. # https://geek-docs.com/django/django-questions/776_django_parsing_fields_in_djangoimportexport_before_importing.html
  20. class PolicyResource(resources.ModelResource):
  21. # 给Resource添加一个自定义字段,指向模型的关系对象,用widget做格式规范
  22. # 关联关系的导入导出, ForeignKeyWidget, ManyToManyWidget
  23. disease_types = fields.Field(
  24. column_name='传染病类型',
  25. attribute='disease_types',
  26. widget=ManyToManyWidget(DiseaseType, separator=',', field='name')
  27. )
  28. def __init__(self, input_contract=None):
  29. super(PolicyResource, self).__init__()
  30. field_list = Policy._meta.fields
  31. self.verbose_name_dict = {}
  32. for i in field_list:
  33. self.verbose_name_dict[i.name] = i.verbose_name
  34. # def get_export_fields(self):
  35. # 默认导入导出field的column_name为字段的名称,这里修改为字段的verbose_name
  36. def get_fields(self): # 导入和导出的表头都需要用 verbose_name
  37. fields = super(PolicyResource, self).get_fields()
  38. for field in fields:
  39. field_name = self.get_field_name(field)
  40. # 如果有设置 verbose_name,则将 column_name 替换为 verbose_name, 否则维持原有的字段名。
  41. if field_name in self.verbose_name_dict.keys():
  42. field.column_name = self.verbose_name_dict[field_name]
  43. return fields
  44. def export(self, queryset=None, *args, **kwargs):
  45. """
  46. Exports a resource.
  47. """
  48. self.before_export(queryset, *args, **kwargs)
  49. if queryset is None:
  50. queryset = self.get_queryset()
  51. headers = self.get_export_headers()
  52. data = tablib.Dataset(headers=headers)
  53. for obj in self.iter_queryset(queryset):
  54. # obj.gender = obj.get_gender_display()
  55. data.append(self.export_resource(obj))
  56. self.after_export(queryset, data, *args, **kwargs)
  57. return data
  58. class Meta:
  59. skip_unchanged = True # 是否跳过的记录出现在导入结果对象
  60. report_skipped = False # 所有记录将被导入
  61. # export_order = ("id","传染病类型","政策类别","政策文件名","政策文件路径","文号","所属国家","发布部门","发布年份","发布日期","实施日期","关键词","时效性","效力级别","创建日期","更新日期","备注")
  62. 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")
  63. model = Policy
  64. verbose_name = True
  65. class MyPolicy(Policy):
  66. class Meta:
  67. proxy = True
  68. verbose_name = "政策批量导入导出"
  69. verbose_name_plural = "政策批量导入导出"
  70. class PolicyExportAdmin(ImportExportModelAdmin):
  71. list_display = ('file_name', 'id', 'category', 'year', 'department', 'publish_date', 'timeliness', 'effectiveness_level',)
  72. list_filter = ('category', 'year', 'department', 'disease_types', )
  73. def has_add_permission(self, request):
  74. return False
  75. def has_change_permission(self, request, obj=None):
  76. return False
  77. # get_queryset方法用于优化查询性能,通过select_related和prefetch_related方法提前加载关联的字段。
  78. def get_queryset(self, request):
  79. queryset = super().get_queryset(request)
  80. # queryset = queryset.select_related('category')
  81. queryset = queryset.prefetch_related('disease_types')
  82. return queryset
  83. # get_ordering方法用于指定默认的排序方式,这里按照publication_year字段进行排序。
  84. def get_ordering(self, request):
  85. return ['year']
  86. resource_class = PolicyResource
  87. class PolicyAdmin(AdvancedSearchAdmin):
  88. list_display = ('file_name', 'id', 'category', 'year', 'department', 'publish_date', 'timeliness', 'effectiveness_level',)
  89. list_filter = ('category', 'year', 'department', 'disease_types', )
  90. search_form = PolicyFormSearch
  91. # get_queryset方法用于优化查询性能,通过select_related和prefetch_related方法提前加载关联的字段。
  92. def get_queryset(self, request):
  93. queryset = super().get_queryset(request)
  94. # queryset = queryset.select_related('category')
  95. queryset = queryset.prefetch_related('disease_types')
  96. return queryset
  97. # get_ordering方法用于指定默认的排序方式,这里按照publication_year字段进行排序。
  98. def get_ordering(self, request):
  99. return ['year']
  100. # def changelist_view(self, request, extra_context=None):
  101. # # 自定义统计逻辑
  102. # # 根据发布年份、发布部门、政策类别、传染病类别和效力级别进行统计
  103. # # 实现你的统计逻辑
  104. # return super().changelist_view(request, extra_context=extra_context)
  105. admin.site.site_header = '中国传染病防治政策数据库'
  106. admin.site.site_title = '中国传染病防治政策数据库'
  107. admin.site.index_title = '中国传染病防治政策数据库'
  108. def get_app_list(self, request, app_label=None):
  109. """
  110. 应用、model 排序
  111. """
  112. app_dict = self._build_app_dict(request, app_label)
  113. if not app_dict:
  114. return
  115. NEW_ADMIN_ORDERING = []
  116. if app_label:
  117. for ao in ADMIN_ORDERING:
  118. if ao[0] == app_label:
  119. NEW_ADMIN_ORDERING.append(ao)
  120. break
  121. if not app_label:
  122. for app_key in list(app_dict.keys()):
  123. if not any(app_key in ao_app for ao_app in ADMIN_ORDERING):
  124. app_dict.pop(app_key)
  125. app_list = sorted(
  126. app_dict.values(),
  127. key=lambda x: [ao[0] for ao in ADMIN_ORDERING].index(x['app_label'])
  128. )
  129. for app, ao in zip(app_list, NEW_ADMIN_ORDERING or ADMIN_ORDERING):
  130. if app['app_label'] == ao[0]:
  131. for model in list(app['models']):
  132. if not model['object_name'] in ao[1]:
  133. app['models'].remove(model)
  134. app['models'].sort(key=lambda x: ao[1].index(x['object_name']))
  135. return app_list
  136. # 模块排序
  137. admin.AdminSite.get_app_list = get_app_list
  138. # 应用名设置成中文
  139. # https://docs.djangoproject.com/en/4.1/ref/applications/#for-application-authors
  140. apps.get_app_config('auth').verbose_name = "系统管理权限"
  141. apps.get_app_config('admin_interface').verbose_name = "界面管理"
  142. admin.site.register(Policy, PolicyAdmin)
  143. admin.site.register(MyPolicy, PolicyExportAdmin)
  144. admin.site.register(DiseaseType)