django import_export 个性化可视化导出外键字段

December 17, 2023
测试
测试
测试
测试
15 分钟阅读

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 = False  # 所有记录将被导入
        # 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)

继续阅读

更多来自我们博客的帖子

如何安装 BuddyPress
由 测试 December 17, 2023
经过差不多一年的开发,BuddyPress 这个基于 WordPress Mu 的 SNS 插件正式版终于发布了。BuddyPress...
阅读更多
Filter如何工作
由 测试 December 17, 2023
在 web.xml...
阅读更多
如何理解CGAffineTransform
由 测试 December 17, 2023
CGAffineTransform A structure for holding an affine transformation matrix. ...
阅读更多