django xadmin 插件(2) 列表視圖新增一功能列


以默認的related_link為例(即最后一列)。

源碼:xadmin.plugins.relate.RelatedMenuPlugin  

class RelateMenuPlugin(BaseAdminPlugin):

    use_related_menu = True

    # ...若干刪減

    def related_link(self, instance):
        #... 若干刪減
        return '<div class="dropdown related_menu pull-right"><a title="%s" class="relate_menu dropdown-toggle" data-toggle="dropdown"><i class="icon fa fa-list"></i></a>%s</div>' % (_('Related Objects'), ul_html)

    related_link.short_description = '&nbsp;'
    related_link.allow_tags = True
    related_link.allow_export = False
    related_link.is_column = False

    def get_list_display(self, list_display):
        if self.use_related_menu and len(self.get_related_list()):
            list_display.append('related_link')
            self.admin_view.related_link = self.related_link
        return list_display

 

注解:

1. 重寫了ListAdminView的get_list_display方法(控制哪些字段加載)。

2. 此處增加的字段是實際數據模型不存在的字段,否則無效。詳細看xadmin.util中的lookup_field方法(需要觸發字段不存在的異常,進入對應名稱的同名方法調用並采用其返回值),源碼如下:

def lookup_field(name, obj, model_admin=None):
    opts = obj._meta
    try:
        f = opts.get_field(name)
    except models.FieldDoesNotExist:
        # For non-field values, the value is either a method, property or
        # returned via a callable.
        if callable(name):
            attr = name
            value = attr(obj)
        elif (model_admin is not None and hasattr(model_admin, name) and
              not name == '__str__' and not name == '__unicode__'):
            attr = getattr(model_admin, name)
            value = attr(obj)
        else:
            attr = getattr(obj, name)
            if callable(attr):
                value = attr()
            else:
                value = attr
        f = None
    else:
        attr = None
        value = getattr(obj, name)
    return f, attr, value

3. 字段的渲染邏輯需要自行實現,此處是 related_link方法, 最終返回html代碼。

4. 自定義字段的html代碼能正常解析,不被和諧,不許要設置方法的allow_tags屬性。

related_link.allow_tags = True

5. 欄位的名稱,通過方法的short_description控制。

related_link.short_description = '&nbsp;'

 

6. (待分析)很神奇的,該插件沒有init_request方法,卻能通過 use_related_menu屬性控制插件是否加載。

新增字段默認返回html代碼,要想其不被和諧, 方法的allow_tags屬性需要為True,如下

related_link.allow_tags = True 

  ---后記---------

      后來分析了下源碼:xadmin/views/base.py (BaseAdminView類的init_plugin方法: 276行)

def init_plugin(self, *args, **kwargs):
        plugins = []
        for p in self.base_plugins:
            p.request = self.request
            p.user = self.user
            p.args = self.args
            p.kwargs = self.kwargs
            import pdb
            pdb.set_trace()
            result = p.init_request(*args, **kwargs)
            if result is not False:
                plugins.append(p)
        self.plugins = plugins

 

 默認情況下, 父類(BaseAdminPlugin)的init_request 不返回任何值,即為None, None is not False, 因此,沒有init_request方法的自定義插件默認加載。之所以貌似能夠用use_related_menu屬性來控制“加載”與否,純粹因為實際邏輯是:

  1. 默認加載控件 

      2. 如果use_related_menu為True,則渲染相關列菜單。否則啥都不做。

  代碼如下:xadmin/plugins/relate.py (79~83)

def get_list_display(self, list_display):
        if self.use_related_menu and len(self.get_related_list()):
            list_display.append('related_link')
            self.admin_view.related_link = self.related_link
        return list_display

 

    

最終效果,就是在列表后追加了一列,如下:

 

轉載請注明來源:http://www.cnblogs.com/Tommy-Yu/p/5417987.html

謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM