針對django xadmin 導出指定字段list_export_fields不生效的解決方案

需求是這樣的,在後臺展示的時候需要展出紅框中的內容,但是在導出的時候需要導出綠框中的字段,

本來覺得是個小小的需求,像xadmin這麼到位的框架,肯定是有的,果斷百度了一圈,果不其然,清清楚楚的寫在人家的博客上。

同時,感謝這位老哥的總結和分享,https://blog.csdn.net/bocai_xiaodaidai/article/details/94395604,贊已經點過了,絕不白嫖。

然後我開開心心的把這個加在我的adminx中,結果發現沒用。。。是真的沒用,上官方查了查,竟然沒找到這個字段!!!

然後又百度和谷歌了一下,不禁感嘆,這難道只有我一個人有這樣的問題嗎?難過之餘,又覺得人家連導出多做好了,我只是選擇幾個字段而已有什麼難的,所以打算看看源碼繼承或者是複寫一下。

下面是我的心路歷程,可能思路清奇,可以直接到下面的做法看看,就是一句話的事。現在的我也知道爲什麼網上沒有找到答案了,可能也是太簡單了,根本不需要分享出來。。。

說時遲那是快,因爲連名字起的也是非常貼心於是很快就找到這個文件了,最終導出的代碼是在xadmin的export插件中,我都是用導出json文件做測試的,

注意這裏的get_json_export中調用了_get_objects來取值

通過幾次debug之後,把目標定在了export.py的這三個函數,在236行左右

    def get_result_list(self, __):
        if self.request.GET.get('all', 'off') == 'on':
            self.admin_view.list_per_page = sys.maxsize
        return __()    
    def result_header(self, item, field_name, row):
        item.export = item.field or field_name == '__str__' or getattr(item.attr, 'allow_export', True)

    def result_item(self, item, obj, field_name, row):
        item.export = item.field or field_name == '__str__' or getattr(item.attr, 'allow_export', True)

全局搜了一下 和他好像有點關聯的就這個list.py,後來又發現原來這個插件原來也是註冊到ListAdminView的,那這感覺離真相又近了一步

果不其然,在list.py中ListAdminView類就有這幾個函數,可以看出是他是循環的list_display之後生成cells屬性來決定輸出的

export.py get_json_export方法中使用的get_objects也應整了這點

xadmin.views.base.filter_hook(func)[source]

 

表明 AdminView 的方法可以被插件插入的裝飾器。執行使用了該裝飾器的方法時,會按照以下過程執行:

  1. 首先將實例的 plugins 屬性取出,取出含有同樣方法名的插件

  2. 按照插件方法的 priority 屬性排序

  3. 順序執行插件方法,執行插件方法的規則:

    • 如果插件方法沒有參數,AdminView 方法的返回結果不爲空則拋出異常

    • 如果插件方法的第一個參數爲 __ ,則 AdminView 方法將作爲第一個參數傳入,注意,這時還未執行該方法, 在插件中可以通過 __() 執行,這樣就可以實現插件在 AdminView 方法執行前實現一些自己的邏輯,例如:

      def get_context(self, __):
          c = {'key': 'value'}
          c.update(__())
          return c
      
    • 如果插件方法的第一個參數不爲 __ ,則執行 AdminView 方法,將結果作爲第一個參數傳入

  4. 最終將插件順序執行的結果返回

 

看到這裏我就決定自己寫一個list_export_fields來用,所以當使用導出插件的時候將list_display=list_export_fields即可實現我們的功能 

下面開始操作

1.在adminx.py中需要選擇字段做導出的添加list_export_fields

class GoodsAdmin(object):
    list_display = ["name", "click_num", "sold_num", "fav_num", "goods_num"]
    
    list_export = ('xls', 'xml', 'json')
    list_export_fields=('name', 'click_num', 'add_time')

2.修改xadmin/plugins/export.py中的ExportPlugin的get_result_list方法

    def get_result_list(self, __):
        if self.request.GET.get('all', 'off') == 'on':
            self.admin_view.list_per_page = sys.maxsize
        self.admin_view.list_display=getattr(self.admin_view,'list_export_fields', self.admin_view.list_display)

        return __()

最終成品,愉快,這個真的當時一直在想怎麼修改插件中的result_headers/result_items,讓他怎麼能循環list_export_fields,後來突然想到直接賦值沒準也行,結果,他真的行。。。。好了,list_export_fields不生效的問題解決完成

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章