需求是這樣的,在後臺展示的時候需要展出紅框中的內容,但是在導出的時候需要導出綠框中的字段,
本來覺得是個小小的需求,像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 的方法可以被插件插入的裝飾器。執行使用了該裝飾器的方法時,會按照以下過程執行:
首先將實例的 plugins 屬性取出,取出含有同樣方法名的插件
按照插件方法的
priority
屬性排序順序執行插件方法,執行插件方法的規則:
如果插件方法沒有參數,AdminView 方法的返回結果不爲空則拋出異常
如果插件方法的第一個參數爲
__
,則 AdminView 方法將作爲第一個參數傳入,注意,這時還未執行該方法, 在插件中可以通過__()
執行,這樣就可以實現插件在 AdminView 方法執行前實現一些自己的邏輯,例如:def get_context(self, __): c = {'key': 'value'} c.update(__()) return c
如果插件方法的第一個參數不爲
__
,則執行 AdminView 方法,將結果作爲第一個參數傳入最終將插件順序執行的結果返回
看到這裏我就決定自己寫一個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不生效的問題解決完成