xadmin插件开发

参考: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)
原文地址:https://www.cnblogs.com/lanqie/p/8340215.html