zoukankan      html  css  js  c++  java
  • 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; auto;text-align: center;display: inline-block;border-1px 0px 0px 1px;">
    {% for row in cp_details %}       
          <div style="clear:left; float:left;auto;">
              {% for o in row %}
                  {% if o.v %}
                      <div class="in222" title="(第{{o.y}}行,第{{o.x}}列)已插卡">&nbsp;</div>
                  {% else %}
                      <div class="empty" title="(第{{o.y}}行,第{{o.x}}列)未插卡" style="border:1px #ff000 solid">&nbsp;</div>
                  {% endif %}
              {% endfor %}
          </div>
    {% endfor %}
    </div>
    </body>
    </html>

    最终效果:

     

    转载请著明来自:http://www.cnblogs.com/Tommy-Yu/p/5443127.html,谢谢!

  • 相关阅读:
    如何使用 IDEA 向 Github 上推送和拉取代码
    CST时间和GMT时间注意事项
    CST时间GMT时间转换
    MultipartFile转InputStream
    Java中InputStream和String之间的转化
    Fastjson 之 Json 对象、Json 字符串、Java 对象之间的转换
    Git 撤销修改
    Springboot 配置文件之 Yaml
    IDEA 快速搭建一个 Springboot 应用
    ZooKeeper 安装
  • 原文地址:https://www.cnblogs.com/Tommy-Yu/p/5443127.html
Copyright © 2011-2022 走看看