安装并配置django-import-export
pip install django-import-export
pip install django-simpleui
配置settings.py
# settings.py
INSTALLED_APPS = (
'simpleui',
'import_export',
)
建立model
from django.db import models
# Create your models here.
# 商品表
class commodity(models.Model):
name = models.CharField(max_length=225, verbose_name="商品名称", blank=True, default="")
desc = models.TextField(verbose_name="商品描述", blank=True)
class Meta:
verbose_name_plural = "商品表"
def __str__(self):
return self.name
生成数据库迁移
python manage.py makemigrations
python manage.py migrate
配置 admin.py
from django.contrib import admin
from app import models
from import_export import resources
from import_export.admin import ImportExportModelAdmin
from django.apps import apps
admin.site.site_header = "XXX后台管理"
admin.site.site_title = "XXX后台"
# Register your models here.
class commodityResource(resources.ModelResource):
def __init__(self):
super(commodityResource, self).__init__()
field_list = models.commodity._meta.fields
self.vname_dict = {}
for i in field_list:
self.vname_dict[i.name] = i.verbose_name
# 默认导入导出field的column_name为字段的名称,这里修改为字段的verbose_name
def get_export_fields(self):
fields = self.get_fields()
for field in fields:
field_name = self.get_field_name(field)
# 如果我们设置过verbose_name,则将column_name替换为verbose_name。否则维持原有的字段名
if field_name in self.vname_dict.keys():
field.column_name = self.vname_dict[field_name]
return fields
def after_import(self, dataset, result, using_transactions, dry_run, **kwargs):
print("after_import")
def after_import_instance(self, instance, new, **kwargs):
print("after_import_instance")
class Meta:
model = models.commodity
skip_unchanged = True
report_skipped = True
fields = ("id", "name", "desc")
@admin.register(models.commodity)
class AppTypeAdmin(ImportExportModelAdmin):
list_display = ("name", "desc")
list_display_links = ("name", "desc")
search_fields = ('name', 'desc')
model_icon = "fa fa-tag"
list_per_page = 50
resource_class = commodityResource
def save_model(self, request, obj, form, change):
super().save_model(request, obj, form, change)
运行效果图如下:
点击导入页面如下:
实现思路如下:
通过重写导入页面,在应用目录(app)下-->templatetags-->apptags.py
配置settings.py
libraries 节点
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
'libraries': {
'apptags': 'app.templatetags.apptags'
},
},
},
]
apptags.py
from django import template
from django.apps import apps
register = template.Library() # 这一句必须这样写
@register.simple_tag(takes_context=True)
def import_head_tag(context):
verbose_names = []
fieldlists = context.dicts[3]["fields"]
opts = str(context.dicts[3]["opts"]).split(".")
for f in fieldlists:
fields = apps.get_model(opts[0], opts[1])._meta.fields
for fs in fields:
if (str(fs).split(".")[-1] == str(f)):
verbose_names.append(fs.verbose_name)
break
return ",".join(verbose_names)
重写django-import-export 导入页面,在项目templates下新建 admin-->import_export--> import.html
import.html代码如下 将{{ fields|join:", " }} 替换成 apptags.py 定义的 import_head_tag 方法即可
{% extends "admin/import_export/base.html" %}
{% load static simpletags apptags %}
{% load i18n %}
{% load admin_urls %}
{% load import_export_tags %}
{% load static %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "import_export/import.css" %}" />{% endblock %}
{% block breadcrumbs_last %}
{% trans "Import" %}
{% endblock %}
{% block content %}
{% if confirm_form %}
<form action="{% url opts|admin_urlname:"process_import" %}" method="POST">
{% csrf_token %}
{{ confirm_form.as_p }}
<p>
{% trans "Below is a preview of data to be imported. If you are satisfied with the results, click 'Confirm import'" %}
</p>
<div class="submit-row">
<input type="submit" class="default" name="confirm" value="{% trans "Confirm import" %}">
</div>
</form>
{% else %}
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>
{% trans "This importer will import the following fields: " %}
<code>{% import_head_tag %} </code>
</p>
<fieldset class="module aligned">
{% for field in form %}
<div class="form-row">
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
{% if field.field.help_text %}
<p class="help">{{ field.field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
</fieldset>
<div class="submit-row"><input type="submit" class="default" value="{% trans "Submit" %}">
</div>
</form>
{% endif %}
{% if result %}
{% if result.has_errors %}
<h2>{% trans "Errors" %}</h2>
<ul>
{% for error in result.base_errors %}
<li>
{{ error.error }}
<div class="traceback">{{ error.traceback|linebreaks }}</div>
</li>
{% endfor %}
{% for line, errors in result.row_errors %}
{% for error in errors %}
<li>
{% trans "Line number" %}: {{ line }} - {{ error.error }}
<div><code>{{ error.row.values|join:", " }}</code></div>
<div class="traceback">{{ error.traceback|linebreaks }}</div>
</li>
{% endfor %}
{% endfor %}
</ul>
{% elif result.has_validation_errors %}
<h2>{% trans "Some rows failed to validate" %}</h2>
<p>{% trans "Please correct these errors in your data where possible, then reupload it using the form above." %}</p>
<table class="import-preview">
<thead>
<tr>
<th>{% trans "Row" %}</th>
<th>{% trans "Errors" %}</th>
{% for field in result.diff_headers %}
<th>{{ field }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in result.invalid_rows %}
<tr>
<td>{{ row.number }} </td>
<td class="errors">
<span class="validation-error-count">{{ row.error_count }}</span>
<div class="validation-error-container">
<ul class="validation-error-list">
{% for field_name, error_list in row.field_specific_errors.items %}
<li>
<span class="validation-error-field-label">{{ field_name }}</span>
<ul>
{% for error in error_list %}
<li>{{ error }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
{% if row.non_field_specific_errors %}
<li>
<span class="validation-error-field-label">{% trans "Non field specific" %}</span>
<ul>
{% for error in row.non_field_specific_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
</li>
{% endif %}
</ul>
</div>
</td>
{% for field in row.values %}
<td>{{ field }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<h2>{% trans "Preview" %}</h2>
<table class="import-preview">
<thead>
<tr>
<th></th>
{% for field in result.diff_headers %}
<th>{{ field }}</th>
{% endfor %}
</tr>
</thead>
{% for row in result.valid_rows %}
<tr>
<td class="import-type">
{% if row.import_type == 'new' %}
{% trans "New" %}
{% elif row.import_type == 'skip' %}
{% trans "Skipped" %}
{% elif row.import_type == 'delete' %}
{% trans "Delete" %}
{% elif row.import_type == 'update' %}
{% trans "Update" %}
{% endif %}
</td>
{% for field in row.diff %}
<td>{{ field }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
{% endif %}
{% endif %}
{% endblock %}
修改后的效果
来源:oschina
链接:https://my.oschina.net/u/4354518/blog/3366222