TasksManager/apps/tasks/admin.py

377 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from datetime import datetime
import re
from django.contrib import admin
from django.http import JsonResponse
from django.utils.html import format_html
from import_export.admin import ImportExportModelAdmin
from import_export.formats import base_formats
from . import models
from apps.users.models import TaskProperty, User
from .resources import TodoResources, TaskResources
class TodoInline(admin.StackedInline):
# 在Inline中同样筛选仅本部门的承办人、协办人
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'related_task':
kwargs["queryset"] = models.Task.objects.filter(department=request.user.department)
elif db_field.name == 'main_executor':
kwargs["queryset"] = User.objects.filter(department=request.user.department)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
def formfield_for_manytomany(self, db_field, request, **kwargs):
if db_field.name == 'sub_executor':
kwargs["queryset"] = User.objects.filter(department=request.user.department)
return super().formfield_for_manytomany(db_field, request, **kwargs)
model = models.Todo
extra = 0
# classes = ['collapse']
#TODO 选择年度任务时排序 https://www.codenong.com/40740869/
class TaskAdmin(ImportExportModelAdmin):
resource_class = TaskResources
# def formfield_for_manytomany(self, db_field, request, **kwargs):
# if db_field.name == "related_task":
# ori_path = request.path
# f_id = re.sub("\D", "", ori_path)
# try:
# kwargs["queryset"] = models.Task.objects.get(id=f_id).related_task
# return super().formfield_for_manytomany(db_field, request, **kwargs)
# except:
# pass
# # kwargs["queryset"] = models.Task.objects.get(id=2).related_task
# 所属单位默认为访问用户的部门
def get_changeform_initial_data(self, request):
return {'department': request.user.department}
# 年度任务编辑界面仅显示本部门的任务属性
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'task_property':
kwargs["queryset"] = TaskProperty.objects.filter(own_department=request.user.department)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
# 仅显示当前部门的年度任务,除非为超管
def get_queryset(self, request):
qs = super(TaskAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
else:
return qs.filter(department=request.user.department)
def save_model(self, request, obj, form, change):
mvDict = dict(request.POST)
# 解决当工作包协办人数均为0时报错
# print(len(mvDict['related_task-0-sub_executor']))
try:
obj.related_task__sub_executor_count = int(len(mvDict['related_task-0-sub_executor']))
except:
obj.related_task__sub_executor_count = 0
super().save_model(request, obj, form, change)
list_display = (
'task_property', 'task_id', 'task_topic', 'task_origin', 'aim_value', 'deadline', 'duty_group', 'principal',
'leader', 'task_note',
)
fieldsets = (
(None, {
'fields': (
('task_property', 'task_id', 'task_topic', 'task_origin', 'aim_value', 'deadline', 'duty_group',
'principal', 'leader'),
'task_note', 'department'),
}),
)
inlines = [TodoInline]
raw_id_fields = ("principal", "leader",)
list_display_links = ('task_topic',)
# autocomplete_fields = ('related_task',)
# search_fields = ('related_task',)
# 导入导出功能限制
def get_export_formats(self): # 该方法是限制格式为XLS
formats = (
base_formats.XLS,
)
return [f for f in formats if f().can_export()]
def has_import_permission(self, request): # 这是隐藏导入按钮,如果隐藏其他按钮也可以这样操作,
if request.user.is_superuser:
return True
else:
return False
# class TodoAdmin(admin.ModelAdmin):
class TodoAdmin(ImportExportModelAdmin):
resource_class = TodoResources
# 工作包页面仅显示所属本部门的年度任务、承办人、协办人
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'related_task':
kwargs["queryset"] = models.Task.objects.filter(department=request.user.department)
elif db_field.name == 'main_executor':
kwargs["queryset"] = User.objects.filter(department=request.user.department)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
def formfield_for_manytomany(self, db_field, request, **kwargs):
if db_field.name == 'sub_executor':
kwargs["queryset"] = User.objects.filter(department=request.user.department)
return super().formfield_for_manytomany(db_field, request, **kwargs)
# 仅显示当前部门的工作包,除非为超管
def get_queryset(self, request):
qs = super(TodoAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
else:
return qs.filter(related_task__department=request.user.department)
fieldsets = [
(None, {
'fields': [
'related_task', 'todo_topic', 'todo_note', 'deadline', 'duty_group', 'main_executor', 'sub_executor',
'sub_executor_count', 'predict_work', 'evaluate_factor', 'real_work'
],
'description': ''
}),
(None, {
'fields': [],
}),
]
list_display = (
'todo_topic',
'deadline',
'todo_note',
'task_id',
'task_origin',
'lined_task',
# 'duty_department',
'duty_group',
'main_executor',
'list_sub_executor',
'predict_work',
'evaluate_factor',
'maturity',
'real_work',
'complete_note',
'quality_mark',
)
list_editable = ['quality_mark']
list_filter = ('deadline',)
list_display_links = ('todo_topic', 'deadline', )
date_hierarchy = 'deadline'
list_per_page = 70 # 目的是取消自动分页好像有bug
# raw_id_fields = ("sub_executor",)
search_fields = ('todo_topic',)
ordering = ('related_task', )
readonly_fields = ["attachment"]
def approval_state(self, obj):
return format_html('<span style="color:{};">{}</span>', 'green', obj.approval)
def task_id(self, obj):
return obj.task_id
task_id.admin_order_field = 'related_task__task_id'
task_id.short_description = '任务编号'
def task_origin(self, obj):
return obj.task_origin
task_origin.short_description = '任务来源'
def duty_department(self, obj):
return obj.duty_group
duty_department.short_description = '责任部门'
def lined_task(self, obj):
return obj.related_task
lined_task.short_description = '任务名称'
# 导入导出功能限制
def get_export_formats(self): # 该方法是限制格式为XLS
formats = (
base_formats.XLS,
)
return [f for f in formats if f().can_export()]
def has_import_permission(self, request): # 这是隐藏导入按钮,如果隐藏其他按钮也可以这样操作,
if request.user.is_superuser:
return True
else:
return False
# 对工作包页面选择其所属的年度任务中,对年度任务进行筛选。条件为:年度任务的完成时间不早于今年或年度任务中有工作包的完成时间晚于今年
def get_form(self, request, obj=None, **kwargs):
form = super(TodoAdmin, self).get_form(request, obj, **kwargs)
query = models.Task.objects.filter(
department=request.user.department, deadline__year__gte=datetime.now().strftime('%Y')).order_by('task_id')\
| models.Task.objects.filter(
department=request.user.department, related_task__deadline__year__gte=datetime.now().strftime('%Y'))\
.order_by('task_id')
form.base_fields['related_task'].queryset = query.distinct()
return form
# def save_model(self, request, obj, form, change):
# # 这一行代码写了一个晚上呜呜! 解决了当保存时,无法从未保存的数据中获取协办人数的问题!
# mvDict = dict(request.POST)
# dicts = request.POST
# print(dicts)
# for key, values in dicts:
# print(key, values)
# obj.user = request.user
# obj.sub_executor_count = int(len(mvDict['sub_executor']))
# super().save_model(request, obj, form, change)
# 增加批量操作按钮
actions = ['bulk_action']
def bulk_action(self, request, queryset):
post = request.POST
# 这里获取到数据后,可以做些业务处理
# post中的_action 是方法名
# post中 _selected 是选中的数据,逗号分割
if not post.get('_selected'):
return JsonResponse(data={
'status': 'error',
'msg': '请先选中数据!'
})
else:
return JsonResponse(data={
'status': 'success',
'msg': '处理成功!'
})
# 显示的文本与django admin一致
bulk_action.short_description = '批量操作'
# icon参考element-ui icon与https://fontawesome.com
bulk_action.icon = 'el-icon-files'
# 指定element-ui的按钮类型参考https://element.eleme.cn/#/zh-CN/component/button
bulk_action.type = 'warning'
# 给按钮追加自定义的颜色
bulk_action.style = 'color:white;'
# 指定为弹出层,这个参数最关键
bulk_action.layer = {
# 弹出层中的输入框配置
# 这里指定对话框的标题
'title': '弹出层输入框',
# 提示信息
'tips': '这个弹出对话框是需要在admin中进行定义数据新增编辑等功能需要自己来实现。',
# 确认按钮显示文本
'confirm_button': '确认提交',
# 取消按钮显示文本
'cancel_button': '取消',
# 弹出层对话框的宽度默认50%
'width': '40%',
# 表单中 label的宽度对应element-ui的 label-width默认80px
'labelWidth': "80px",
'params': [{
# 这里的type 对应el-input的原生input属性默认为input
'type': 'input',
# key 对应post参数中的key
'key': 'name',
# 显示的文本
'label': '名称',
# 为空校验默认为False
'require': True
}, {
'type': 'select',
'key': 'type',
'label': '类型',
'width': '200px',
# size对应elementui的size取值为medium / small / mini
'size': 'small',
# value字段可以指定默认值
'value': '0',
'options': [{
'key': '0',
'label': '收入'
}, {
'key': '1',
'label': '支出'
}]
}, {
'type': 'number',
'key': 'money',
'label': '金额',
# 设置默认值
'value': 1000
}, {
'type': 'date',
'key': 'date',
'label': '日期',
}, {
'type': 'datetime',
'key': 'datetime',
'label': '时间',
}, {
'type': 'rate',
'key': 'star',
'label': '评价等级'
}, {
'type': 'color',
'key': 'color',
'label': '颜色'
}, {
'type': 'slider',
'key': 'slider',
'label': '滑块'
}, {
'type': 'switch',
'key': 'switch',
'label': 'switch开关'
}, {
'type': 'input_number',
'key': 'input_number',
'label': 'input number'
}, {
'type': 'checkbox',
'key': 'checkbox',
# 必须指定默认值
'value': [],
'label': '复选框',
'options': [{
'key': '0',
'label': '收入'
}, {
'key': '1',
'label': '支出'
}, {
'key': '2',
'label': '收益'
}]
}, {
'type': 'radio',
'key': 'radio',
'label': '单选框',
'options': [{
'key': '0',
'label': '收入'
}, {
'key': '1',
'label': '支出'
}, {
'key': '2',
'label': '收益'
}]
}]
}
admin.site.register(models.Task, TaskAdmin)
admin.site.register(models.Todo, TodoAdmin)