参考:http://blog.csdn.net/qq_15682489/article/details/70174784
项目中新添加的organization模块需要在toolbar中添加“课表详细”,“导入”的功能,这就需要开发插件。
文件:
├── adminx.py
├── apps.py
├── __init__.py
├── models.py
├── plugins.py
└── views.py
templates目录下:
└── xadmin
├── plugins
│ ├── model_list.top_toolbar.format.html
│ └── model_list.top_toolbar.importexport.import.html
└── views
└── schedule_query.html
model_list.top_toolbar.format.html:
schedule_query.html:
model_list.top_toolbar.importexport.import.html:
plugins.py:
from json import JSONEncoder from django.template import loader
from django.template.response import TemplateResponse from utils.dataUtils import replace_html
from xadmin.views import BaseAdminPlugin
from xadmin.plugins.actions import BaseActionView
from .models import *
import json, re #显示插件
class QueryMenuPlugin(BaseAdminPlugin):
demo_query_menu = False def init_request(self, *args, **kwargs):
#指定特定页面显示插件
self.demo_query_menu = self.request.get_full_path().endswith('schedule/')
return self.demo_query_menu
#toolbar中插件显示页面
def block_top_toolbar(self, context, nodes):
if self.demo_query_menu:
nodes.append(
loader.render_to_string('xadmin/plugins/model_list.top_toolbar.format.html',
context_instance=context)
) class QueryView(BaseActionView):
def do_action(self, context):
return TemplateResponse(self.request, self.get_template_list('views/schedule_query.html'), context,
current_app=self.admin_site.name) #这个插件不需要在toolbar中显示,不需要block_top_toolbar函数,而是显示一个新的View,
class QueryPlugin(BaseAdminPlugin):
def init_request(self, *args, **kwargs):
#特定请求才显示该插件
return self.request.GET.get('q') == 'schedule' def response_action(self, ac, context):
if isinstance(ac, type) and issubclass(ac, BaseActionView):
action_view = self.get_model_view(ac, self.admin_view.model)
action_view.init_action(self.admin_view)
return action_view.do_action(context)
else:
return ac(self.admin_view, self.request, context) def get_response(self, response, context, *args, **kwargs):
teacher_id = self.request.GET.get('_p_teacher__id__exact')
clazz_id = self.request.GET.get('_p_clazz__id__exact')
schedule_list = []
select_clazz = ''
select_teacher = ''
try:
if teacher_id and clazz_id:
schedule_list = Schedule.objects.filter(teacher_id=int(teacher_id)).filter(clazz_id=int(clazz_id))
select_clazz = Class.objects.filter(id=int(clazz_id)).first()
select_teacher = Teacher.objects.filter(id=int(teacher_id)).first()
elif teacher_id:
schedule_list = Schedule.objects.filter(teacher_id=int(teacher_id))
select_teacher = Teacher.objects.filter(id=int(teacher_id)).first()
elif clazz_id:
schedule_list = Schedule.objects.filter(clazz_id=int(clazz_id))
select_clazz = Class.objects.filter(id=int(clazz_id)).first()
except:
pass session_list = Session.objects.all().order_by("start_time")
str = '['
for se in schedule_list:
str += (json.dumps(se, default=Schedule.all_schedule2json))
str += ','
str = str[0:str.__len__() - 1]
str += ']'
str = replace_html(str)
context.update({
'session_list': session_list,
'schedule_list': schedule_list,
'str': str,
'select_clazz': select_clazz,
'select_teacher': select_teacher,
})
return self.response_action(QueryView, context) # excel 导入
class ListImportExcelPlugin(BaseAdminPlugin):
import_excel = False def init_request(self, *args, **kwargs):
return bool(self.import_excel) def block_top_toolbar(self, context, nodes):
nodes.append(
loader.render_to_string('xadmin/plugins/model_list.top_toolbar.importexport.import.html',
context_instance=context))
model_list.top_toolbar.format.html:
{% load i18n %}
<div class="btn-group export">
<a class="btn btn-primary btn-sm" data-toggle="modal" href="?q=schedule">
<i class="fa fa-money"></i>课表详细
</a> </div>
schedule_query.html:
{% extends base_template %}
{% load i18n l10n %}
{% load xadmin_tags %} {% block breadcrumbs %}
<ul class="breadcrumb">
<li><a href="{% url 'xadmin:index' %}">{% trans 'Home' %}</a></li>
<li><a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a></li>
<li>课表详细</li>
</ul>
{% endblock %} {% block content %}
<div>当前班级:{{ select_clazz }},当前讲师:{{ select_teacher }}</div>
<table class="table table-bordered table-hover table-condensed">
<thead>
<tr>
<th>节次\星期</th>
<th>星期一</th>
<th>星期二</th>
<th>星期三</th>
<th>星期四</th>
<th>星期五</th>
<th>星期六</th>
<th>星期日</th> </tr>
</thead>
<tbody>
{% for s in session_list %}
<tr>
<td>{{ s.name }}</td>
<td data-session="第{{ forloop.counter }}节" data-week="1"></td>
<td data-session="第{{ forloop.counter }}节" data-week="2"></td>
<td data-session="第{{ forloop.counter }}节" data-week="3"></td>
<td data-session="第{{ forloop.counter }}节" data-week="4"></td>
<td data-session="第{{ forloop.counter }}节" data-week="5"></td>
<td data-session="第{{ forloop.counter }}节" data-week="6"></td>
<td data-session="第{{ forloop.counter }}节" data-week="7"></td> </tr>
{% endfor %} </tbody>
</table> <div class="form-actions well well-sm">
<form method="post" action="">{% csrf_token %}
<button class="btn btn-default"><i class="fa fa-backward"></i> 返回</button>
</form>
</div>
<script src="/static/js/jquery-1.9.1.min.js"></script>
<script> function escape2Html(str) {
var arrEntities = {'lt': '<', 'gt': '>', 'nbsp': ' ', 'amp': '&', 'quot': '"'};
return str.replace(/&(lt|gt|nbsp|amp|quot);/ig, function (all, t) {
return arrEntities[t];
});
} var str = '{{ str }}';
var session_index;
var week_index;
str = escape2Html(str);
jsonObjList = JSON.parse(str);
for (var i = 0; i < jsonObjList.length; i++) {
session_index = jsonObjList[i].session
week_index = jsonObjList[i].week
if ('{{ select_clazz }}' && '{{ select_teacher }}' ){
$("td[data-session=" + session_index + "][data-week=" + week_index + "]").html(jsonObjList[i].subject+'<br>'+jsonObjList[i].classroom);
continue; }else if('{{ select_clazz }}'){
$("td[data-session=" + session_index + "][data-week=" + week_index + "]").html(jsonObjList[i].subject+'<br>'+jsonObjList[i].teacher+'<br>'+jsonObjList[i].classroom);
continue; }else if('{{ select_teacher }}'){
$("td[data-session=" + session_index + "][data-week=" + week_index + "]").html(jsonObjList[i].subject+'<br>'+jsonObjList[i].clazz+'<br>'+jsonObjList[i].classroom);
continue; } } </script>
{% endblock %}
views.py:
from django.shortcuts import render # Create your views here.
from django.views.generic.base import View
from django.http import HttpResponse, HttpResponseRedirect
from .models import *
import xlrd def import_excel(request):
excel = xlrd.open_workbook(
filename=None, file_contents=request.FILES.get('excel').read()) # 关键点在于这里
schedule_list = []
table = excel.sheets()[0]
nrows = table.nrows
ncols = table.ncols
HEAD = ['星期', '节次', '教师', '学科', '教室', '班级']
table_head = table.row_values(0)
if table_head != HEAD:
render(request, "500.html", {'msg': '数据头部错误,必须是' + "['星期', '节次', '教师', '学科', '教室', '班级']" + ",顺序不可变!"}) for i in range(nrows):
if i > 0:
schedule_list.append(table.row_values(i)) try:
insertSchedule(schedule_list)
except:
render(request, "500.html", {'msg': '部分内容不和法,请检查'}) return HttpResponseRedirect("/admin/organization/schedule/") def insertSchedule(schedule_list):
for item in schedule_list:
try:
week = item[0].strip()
session = item[1].strip()
teacher = item[2].strip()
subject = item[3].strip()
classroom = item[4].strip()
clazz = item[5].strip()
f_session = Session.objects.get(name=session)
# 需要判断同名的老师
f_teacher = Teacher.objects.get(user__username=teacher)
f_subject = Subject.objects.get(name=subject)
f_classroom = Classroom.objects.get(name=classroom)
f_clazz = Class.objects.get(name=clazz)
sc = Schedule()
sc.week = getWeek(week)
sc.session = f_session
sc.teacher = f_teacher
sc.subject = f_subject
sc.classroom = f_classroom
sc.clazz = f_clazz
sc.save()
except:
raise Exception("error") def getWeek(week):
switcher = {
"星期一": "1",
"星期二": "2",
"星期三": "3",
"星期四": "4",
"星期五": "5",
"星期六": "6",
"星期日": "7",
}
return switcher.get(week, "1")
model_list.top_toolbar.importexport.import.html:
{% load i18n %}
<div class="btn-group export">
<a class="dropdown-toggle btn btn-default btn-sm" data-toggle="dropdown" href="#">
<i class="icon-share"></i> 导入 <span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
<li><a data-toggle="modal" data-target="#export-modal-import-excel"><i class="icon-circle-arrow-down"></i> 导入
Excel</a></li>
</ul>
<script>
function fileChange(target) {
//检测上传文件的类型
var imgName = document.all.submit_upload.value;
var ext, idx;
if (imgName == '') {
document.all.submit_upload_b.disabled = true;
alert("请选择需要上传的 xls 文件!");
return;
} else {
idx = imgName.lastIndexOf(".");
if (idx != -1) {
ext = imgName.substr(idx + 1).toUpperCase();
ext = ext.toLowerCase();
{# alert("ext="+ext);#}
if (ext != 'xls' && ext != 'xlsx') {
document.all.submit_upload_b.disabled = true;
alert("只能上传 .xls 类型的文件!");
return;
}
} else {
document.all.submit_upload_b.disabled = true;
alert("只能上传 .xls 类型的文件!");
return;
}
}
}
</script>
<div id="export-modal-import-excel" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<form method="post" action="/admin/organization/schedule/import_excel" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">导入 Excel</h4>
</div>
<div class="modal-body">
<input type="file" onchange="fileChange(this)" name="excel" id="submit_upload">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button>
<button class="btn btn-success" type="submit" id="submit_upload_b"><i class="icon-share"></i> 导入
</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dalog -->
</div><!-- /.modal --> </div>
注册插件
xadmin:
xadmin.site.register_plugin(QueryMenuPlugin, ListAdminView)
xadmin.site.register_plugin(QueryPlugin, ListAdminView)
xadmin.site.register_plugin(ListImportExcelPlugin, ListAdminView)