Xadmin导入excel数据及再加工数据和优化预览记录的总结
导入excel数据
class GoodsCustomerAdmin(object):
import_export_args = {'import_resource_class': GoodsCustomerResources, }
resource_class = GoodsCustomerResources
import_export_args :用于指定导入菜单,默认已有导出菜单了。
save_models(适合新建记录后加工处理)
备注:此方法重写的是单记录操作,如果是批量导入数据的话,是不奏效的。
换一句话说:你在changelist页面点击保存或才会执行这个save。
def save_models(self):
obj = self.new_obj # 此obj 代表的是模型处于编辑状态下的记录(行)
bind = list(GoodsCompany.objects.values_list('goods_bind', flat=True))
no = list(GoodsCompany.objects.values_list('goods_no', flat=True))
query = '%s %s %s' % (obj.goods_name, obj.spec, obj.manufacturer)
result = process.extractOne(query, bind, score_cutoff=90)
if result:
obj.goods_bind = result[0]
idx = bind.index(result[0])
obj.goods_company = no[idx]
super().save_models()
缩减导入数据的预览表格行数
当你导入10000行数据的时候,阅览数据意义不大。既然自己导入,自然是先加工好的,所以,只要展示表头或几行数据就够了,确认下是不是导入对了表格。
1、找到路径:xadmin\plugins\importexport(xadmin包源码)
大概在156行处,可以找到ImportView视图;
再往下,在234行处:
result = resource.import_data(dataset, dry_run=True,
raise_errors=False,
file_name=import_file.name,
user=request.user)
在context[‘result’] = result后增加下边语句:
# 取result前N行作为预览页面的N行数据
if len(result.rows) < 20: # 20这个数据自由修改
result2 = result.rows
else:
result2 = result.rows[:20]
context['result2'] = result2
context[‘result2’]作用是通过TemplateResponse传入result2变量。
2、修改模板
找到路径:templates/xadmin/import_export/import.html(xadmin包源码)
在大约99行位置,
将{% for row in result.rows %}改成{% for row in result2 %}
数据批量导入前预处理
导入流程简要说明:import_data是import-export第三方库导入数据的核心函数,里边包含了很多预处理数据的函数。但是有个蛋疼的地方。这个导入数据大概的流程是先把导入的数据读取后放到临时文件中,会用到一次import_data。然后阅览确认后再从临时文件import_data到数据库。
例子:模糊匹配商品
before_save_instance:其中instance参数就是每一行导入数据object。
def before_save_instance(self, instance, using_transactions, dry_run):
goods_no = instance.goods_no
customer_no = instance.customer_no
try:
GoodsCustomer.objects.get(goods_no=goods_no, customer_no=customer_no)
except GoodsCustomer.DoesNotExist:
query = '%s %s %s' % (instance.goods_name, instance.spec, instance.manufacturer)
bind = list(GoodsCompany.objects.values_list('goods_bind', flat=True))
no = list(GoodsCompany.objects.values_list('goods_no', flat=True))
result = process.extractOne(query, bind, score_cutoff=90)
if result:
instance.goods_bind = result[0]
idx = bind.index(result[0])
instance.goods_company = no[idx]
我试了一个预处理,由于这个import_data用了两次,每次都会调用before_save_instance,结果你懂得,不是重复操作一次预处理嘛。
所以,如果预处理结果复杂及条目数多的情况,还是换成其他办法来处理。
导入数据后的信息展示
1、在django官方文档,找到Common Web application tools部分,里边有一个“Messages framework”,里边详细介绍了怎么应用消息通知。
2、xadmin文档的base.html中,大约在44行{% view_block ‘extrabody’ %}后,添加如下代码:
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>
{% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}Important: {% endif %}
{{ message }}
</li>
{% endfor %}
</ul>
{% endif %}
3、其实在Xadmin的importexport.py中ImportProcessView视图已经添加了消息:
success_message = str(_(u'Import finished')) + ' , ' + str(_(u'Add')) + ' : %d' % result.totals[
RowResult.IMPORT_TYPE_NEW] + ' , ' + str(_(u'Update')) + ' : %d' % result.totals[
RowResult.IMPORT_TYPE_UPDATE]
messages.success(request, success_message)
结合第2步,就会在预览数据确认后,等全部导入完成后就会在列表页的上头增加一条蓝色的条框,里边就会显示:导入完毕,一共更新了N条记录。