需求是这样的,在后台展示的时候需要展出红框中的内容,但是在导出的时候需要导出绿框中的字段,
本来觉得是个小小的需求,像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不生效的问题解决完成