django xadmin 插件(3) 列表视图新增自定义按钮
效果图:
编辑按钮是默认的list_editable属性对应的插件(xadmin.plugins.editable)
放大按钮对应的是自定义插件。
自定义按钮源码:
xplugin.py(保证能够直接或者间接被adminx.py引用到即可)
# -*- coding:utf-8 -*- import xadmin from xadmin.views import BaseAdminPlugin, ListAdminView from xadmin.views.edit import ModelFormAdminUtil from xadmin.util import label_for_field from django.utils.translation import ugettext as _ class CustomDetailPlugin(BaseAdminPlugin): custom_details={} def __init__(self, admin_view): super(CustomDetailPlugin, self).__init__(admin_view) self.editable_need_fields = {} def init_request(self, *args, **kwargs): active = bool(self.request.method == 'GET' and self.admin_view.has_view_permission() and self.custom_details) if active: self.model_form = self.get_model_view(ModelFormAdminUtil, self.model).form_obj return active def result_item(self, item, obj, field_name, row): if self.custom_details and item.field and (field_name in self.custom_details.keys()): pk = getattr(obj, obj._meta.pk.attname) field_label = label_for_field(field_name, obj, model_admin=self.admin_view, return_attr=False) item.wraps.insert(0, '<span class="editable-field">%s</span>') title=self.custom_details.get(field_name,{}).get('title',_(u"Details of %s") % field_label) default_load_url=self.admin_view.model_admin_url('patch', pk) + '?fields=' + field_name load_url = self.custom_details.get(field_name,{}).get('load_url',default_load_url) if load_url!=default_load_url: concator='?' if load_url.find('?')==-1 else '&' load_url=load_url+concator+'pk='+str(pk) item.btns.append(( '<a class="editable-handler" title="%s" data-editable-field="%s" data-editable-loadurl="%s">'+ '<i class="fa fa-search"></i></a>') % (title, field_name,load_url) ) if field_name not in self.editable_need_fields: self.editable_need_fields[field_name] = item.field return item # Media def get_media(self, media): if self.editable_need_fields: media = media + self.model_form.media + \ self.vendor( 'xadmin.plugin.editable.js', 'xadmin.widget.editable.css') return media xadmin.site.register_plugin(CustomDetailPlugin, ListAdminView)
基本抄写了xadmin.plugins.editable的源码,并做少量修改。
1. 增加custom_details 字段 {字段名:{'title':自定义弹框标题, 'load_url':自定义弹框所加载的url地址},...}
此url后续增加get参数: pk=n , 一起被xadmin.plugin.editable.js做get方式的ajax读取,并将读取到的html赋值到弹框里面。
因此自定义功能很大程度依赖于url对应的页面的实现。
2. 默认的编辑按钮改成了放大镜(可以提取为属性供adminx中的类自定义)
js/css都沿用原来的。并对 xadmin.plugin.editable.js做了少量阉割(注释以下两行代码,避免自定义icon被恢复为编辑图标)。
Editpop.prototype.beforeToggle = function() { var $el = this.$element if(this.content == null){ var that = this //$el.find('>i').removeClass('fa fa-edit').addClass('fa-spinner fa-spin') $.ajax({ url: $el.data('editable-loadurl'), success: function(content){ //$el.find('>i').removeClass('fa-spinner fa-spin').addClass('fa fa-edit') that.content = content that.toggle() }, dataType: 'html' }) } else { this.toggle() } }
备注:
自定义弹框原理:
ajax get方式加载url: cust_details[字段名]['load_url']?pk=n(n为对应模型实例的主键id)
将加载得到的html显示在弹出的窗体中。
应用示例
adminx.py
class SimCardPoolAdmin(object): #... custom_details={'card_in':{'title':u'xx明细', 'load_url':'detail2'}}
views.py (details2的试图&菜单注册)
# -*- coding:utf-8 -*- from xadmin.sites import site from xadmin.views.base import CommAdminView,csrf_protect_m from django.template.response import TemplateResponse from .models import * class CardPoolCardsView(CommAdminView): #base_template = 'xadmin/base_site.html' @csrf_protect_m def get(self, request, *args, **kwargs): pid = request.GET['pk'] pool_obj = SimCardPool.objects.get(id=pid) card_objs=SimCardPhy.objects.filter(pool_no=pool_obj.pool_no) data = [[{'x':x+1,'y':y+1,'v':0} for x in range(pool_obj.cols)] for y in range(pool_obj.rows)] for c in card_objs: data[c.row-1][c.col-1]['v']=1 import pdb #context = self.get_context() context={'cp_details':data, 'rows':range(1,pool_obj.rows+1), 'cols':range(1,pool_obj.cols+1)} #pdb.set_trace() return TemplateResponse(self.request, [ 'card_pool/cp_details.html' ], context, current_app=self.admin_site.name) site.register_view(r'^card_pool/simcardpool/detail2/$',CardPoolCardsView, name='cp_detail')
xadmin此版本貌似不能加载views.py,作为破解在 __init__.py中增加了 import views一行,如下:
__init__.py
import views
相关模板
<html> <head> <style type="text/css"> .in222{ background-color: green; width: 14px;height: 14px; float:left; border:solid #add9c0; border-width:0px 1px 1px 0px; } .empty{ background-color: #eeeeff; border:1px #ff000 solid; width: 14px;height: 14px; float:left; border:solid #add9c0; border-width:0px 1px 1px 0px; } </style> </head> <body> <div style="border:solid 1px #add9c0; width:auto;text-align: center;display: inline-block;border-width:1px 0px 0px 1px;"> {% for row in cp_details %} <div style="clear:left; float:left;width:auto;"> {% for o in row %} {% if o.v %} <div class="in222" title="(第{{o.y}}行,第{{o.x}}列)已插卡"> </div> {% else %} <div class="empty" title="(第{{o.y}}行,第{{o.x}}列)未插卡" style="border:1px #ff000 solid"> </div> {% endif %} {% endfor %} </div> {% endfor %} </div> </body> </html>
最终效果:
转载请著明来自:http://www.cnblogs.com/Tommy-Yu/p/5443127.html,谢谢!