20、Django导入导出功能
第一步:安装插件
pip install django-import-export
第二部:更新settings.py配置
INSTALLED_APPS = (
...
'import_export',
)
第三部:在admin.py文件中写入如下代码
from django.contrib import admin
from .models import Article
from import_export.admin import ImportExportModelAdmin
# 自定义模型管理类
@admin.register(Article)
class ArticleAdmin(ImportExportModelAdmin):
list_display = ("id", "title", "author", "content", "score", "pub_date", "update_date", "full_name")
list_display_links = ("title", "content")
list_per_page = 10
list_filter = ("title", "author")
search_fields = ("title", "content")
优化:
如果字段太多,只想导出一部分内容怎么办
from import_export import resources
class ArticleResource(resources.ModelResource):
class Meta:
model = Article
#导出内容
fields = ("id", "title", "author",)
# 导出顺序
export_order = ("id", "title", "author")
class ArticleAdmin(ImportExportModelAdmin):
'''略'''
resource_class = ArticleResource
导出的数据表头是英文,我想要中文 verbose_name 的备注
class ArticleResource(resources.ModelResource):
# 默认导入导出field的column_name为字段的名称,这里修改为字段的verbose_name
def __init__(self, input_contract=None):
super(ArticleResource, self).__init__()
field_list = Article._meta.fields
self.verbose_name_dict = {}
for i in field_list:
self.verbose_name_dict[i.name] = i.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.verbose_name_dict.keys():
field.column_name = self.verbose_name_dict[field_name]
return fields
class Meta:
model = Article
#导出内容
fields = ("id", "title", "author",)
# 导出顺序
export_order = ("id", "title", "author")
例如
models.py
class Article(models.Model):
"""
主题表/文章表
"""
title = models.CharField(max_length=128, unique=True, verbose_name="标题", help_text="请填写标题")
slug = models.SlugField(max_length=128, unique=True, verbose_name="url标识符")
content = RichTextUploadingField(verbose_name="内容", config_name='awesome_ckeditor', )
node = models.ForeignKey(Node, on_delete=models.DO_NOTHING, verbose_name="所属节点")
user = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name="user_article", verbose_name="作者")
source = models.ForeignKey(Source, on_delete=models.DO_NOTHING, verbose_name="来源", blank=True, null=True)
tags = models.ManyToManyField(Tag, verbose_name="标签", related_name="tags_article", blank=True)
num_views = models.IntegerField(default=0, verbose_name="浏览数量")
num_favorites = models.IntegerField(default=0, verbose_name="收藏数量")
last_answerer = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name="last_answerer_article",
verbose_name="最后回复者", blank=True,
null=True)
show_status = models.BooleanField(default=True, verbose_name="显示状态")
time_create = models.DateTimeField(auto_now_add=True, verbose_name="发表时间")
time_update = models.DateTimeField(blank=True, null=True, auto_now=True, verbose_name="更新时间")
admins.py
from django.contrib import admin
from django.forms import widgets
from apps.blog.models import *
from apps.blog.forms import ArticleAdminForm
from django.contrib.admin import SimpleListFilter
from django.utils.html import format_html
from import_export import resources, fields
from import_export.admin import ImportExportModelAdmin
from import_export.admin import ImportExportActionModelAdmin
from import_export.admin import ExportActionMixin
from import_export.widgets import ForeignKeyWidget
from django.contrib.auth import get_user_model
User = get_user_model()
# https://github.com/django-import-export/django-import-export/issues/758
# Register your models here.
class ArticleResource(resources.ModelResource):
# 外键可视化导出
user = fields.Field(
column_name='user',
# user 在本模型外键的字段名称
attribute='user',
# username 外键的里面的字段名
widget=ForeignKeyWidget(User, 'username'))
last_answerer = fields.Field(
column_name='last_answerer',
attribute='last_answerer',
widget=ForeignKeyWidget(User, 'username'))
def __init__(self, input_contract=None):
super(ArticleResource, self).__init__()
field_list = Article._meta.fields
self.verbose_name_dict = {}
for i in field_list:
self.verbose_name_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.verbose_name_dict.keys():
field.column_name = self.verbose_name_dict[field_name]
return fields
class Meta:
skip_unchanged = True # 是否跳过的记录出现在导入结果对象
report_skipped = True # 所有记录将被导入
# export_order = ('id', )
model = Article
class ArticleAdmin(ImportExportActionModelAdmin):
# change_list_template = "change_list_custom.html" # 自定义的模板名称
form = ArticleAdminForm # 指定了表单,就不要再用 formfield_overrides 了
def get_actions(self, request):
# 列表禁用删除操作
actions = super(ArticleAdmin, self).get_actions(request)
if 'delete_selected' in actions and not request.user.is_superuser:
del actions['delete_selected']
return actions
def has_add_permission(self, request, obj=None):
# 编辑和列表页面非超管禁用 add 按钮
if request.user.is_superuser:
return True
return False
def show_status_button(self, obj):
return format_html('<a href="{}" title="查看站点">{}</a>', obj.id, obj.show_status)
show_status_button.short_description = "审核"
def get_list_display(self, request):
"""
Return a sequence containing the fields to be displayed on the
changelist.
"""
if request.user.is_superuser:
list_display = ['id', 'thumb_shouw', 'title', 'node', 'num_views', 'show_status', 'slug', 'user',
'show_status_button', 'time_create']
return list_display
else:
list_display = ['thumb_shouw', 'title', 'node', 'num_views', 'show_status', 'slug', 'user',
'show_status_button', ]
return list_display
# list_display = ['id', 'thumb_shouw', 'title', 'node', 'num_views', 'show_status', 'slug', 'user',
# 'show_status_button', 'time_create']
list_display_links = ['id', 'thumb_shouw', 'title', 'node', 'num_views', 'user']
list_filter = ['id', 'source__name', NodeFilter]
search_fields = ['title_short', 'user', 'content']
# list_editable = ["show_status", ]
# style_fields = {"content": "ueditor"}
readonly_fields = ('slug',)
show_detail_fields = ['show_status', ]
resource_class = ArticleResource
admin.site.register(Article, ArticleAdmin)
Last updated