django-import-export工具包笔记

Django项目需要数据导入及导出,使用django-import-export实现

1.安装

pip install django-import-export==2.7.1

2.setting.py文件

INSTALLED_APPS = [
    ...
    'import_export',
]```

3.admin.py文件

```python
from django.contrib import admin
from import_export.admin import ImportExportModelAdmin
# 修改model路径
from ...models import Sample
# 修改resource路径(resource.py文件为新建文件)
from ...resource import SampleResource
class CommonAdmin(ImportExportModelAdmin):
    """统一封装 添加id过滤"""
    list_filter = ('id', )

    def get_list_display(self, request):
        """展示字段"""
        return [field.name for field in self.model._meta.fields]
 
@admin.register(Sample)
class SampleAdmin(CommonAdmin):
    """SampleAdmin"""
    resource_class = SampleResource

4.model.py文件

class Dataset(models.Model):
    """
        Dataset
    """
    dataset_id = models.CharField(max_length=255, primary_key=True)
    title = models.CharField(max_length=255)


class Sample(models.Model):
    """
        Sample
    """
    dataset = models.ForeignKey(Dataset, on_delete=models.CASCADE)
    sample_id = models.CharField(max_length=255)
    sample_name = models.CharField(max_length=255, default='', blank=True)

5.resource.py 文件

class SampleResource(CommonResource):
    """
    SampleResources
    """
    # 此处dataset_id为外键关联,因此需定义dataset
    dataset = fields.Field(
        column_name='dataset_id',
        attribute='dataset',
        widget=ForeignKeyWidget(Dataset, 'dataset_id'))

    class Meta:
        """
        Meta
        """
        model = Sample
        # skip_diff开启会导致django-admin上传时显示空白,但是能正常导入
        skip_diff = True
        # 数据一致则跳过
        skip_unchanged = True
        # 设置数据库事务,一个失败全部回滚
        use_transactions = True
        # 导入每行都创建实例,用于触发Model的save函数。便于signal信号函数调用
        force_init_instance = True
        # 设置批量导入
        use_bulk = True
        batch_size = 1000
	
	# 导入数据后逻辑(根据业务需求调整)
    def after_import(self, dataset, result, using_transactions, dry_run, **kwargs):
        """上传数据后,更新es数据库中的sample字段 每次仅上传一个数据集"""
        super().after_import(dataset, result, using_transactions, dry_run, **kwargs)
        if not dry_run:
            dataset_id = dataset.dict[0]['dataset_id'] if dataset.dict else None
            if dataset_id:
                dataset = Dataset.objects.get(dataset_id=dataset_id)
                sample_data = get_nested_sample(dataset)
                document = DatasetDocument.get(id=dataset_id)
                document.sample = sample_data
                document.save()

临时文件目录更改

背景:django-import-export在上传文件时会在系统的临时文件目录下创建临时文件,上传完成后再删掉文件。可根据需要对临时文件目录进行重写。
1.setting.py文件

# 自定义临时文件函数
IMPORT_EXPORT_TMP_STORAGE_CLASS = '***.import_tools.CustomTempFolderStorage'
# 自定义临时文件目录
PROJECT_TMP_FOLDER=/***/tmp/

2.import_tools.py文件

"""自定义导入模块临时文件路径"""
import os
import tempfile
from django.conf import settings
from import_export.tmp_storages import BaseStorage


class CustomTempFolderStorage(BaseStorage):
    """重写TempFolderStorage"""
    temp_folder = settings.PROJECT_TMP_FOLDER

    def __init__(self, name=None):
        """初始化临时文件路径"""
        super().__init__(name)
        # 确保目录存在
        if not os.path.exists(self.temp_folder):
            os.makedirs(self.temp_folder)

    def open(self, mode='r'):
        """创建临时文件"""
        if self.name:
            return open(self.get_full_path(), mode)  # pylint:disable=W1514

        # dir:设置路径
        tmp_file = tempfile.NamedTemporaryFile(delete=False, dir=self.temp_folder)  # pylint:disable=R1732
        self.name = tmp_file.name
        return tmp_file

    def save(self, data, mode='w'):
        """保存临时文件"""
        with self.open(mode=mode) as file:
            file.write(data)

    def read(self, mode='r'):  # pylint:disable=W0237
        """读取临时文件路径"""
        with self.open(mode=mode) as file:
            return file.read()

    def remove(self):
        """删除临时文件"""
        os.remove(self.get_full_path())

    def get_full_path(self):
        """获取临时文件存放路径"""
        return os.path.join(self.temp_folder, os.path.basename(self.name))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值