基于Django import_export实现不区分大小写外键导入并自动创建实例
Django import_export 处理含 ForeignKey 模型的导入问题解决
一、按名称(不区分大小写)匹配并自动创建 Author
1. 自定义 ForeignKeyWidget
要实现不区分大小写检查+自动创建逻辑,需要重写ForeignKeyWidget的核心方法:
from import_export.widgets import ForeignKeyWidget from .models import Author class CaseInsensitiveAuthorWidget(ForeignKeyWidget): def get_queryset(self, value, row, *args, **kwargs): # 用__iexact实现不区分大小写过滤 return self.model.objects.filter(name__iexact=value.strip()) def clean(self, value, row=None, *args, **kwargs): if not value: return None # 优先匹配已有作者 queryset = self.get_queryset(value, row) if queryset.exists(): return queryset.first() # 无匹配则自动创建新作者 return self.model.objects.create(name=value.strip())
2. 在资源类中绑定自定义 Widget
在Book的资源类里,给author字段指定上述自定义Widget:
from import_export import resources, fields from .models import Book class BookResource(resources.ModelResource): author = fields.Field( column_name='author', attribute='author', widget=CaseInsensitiveAuthorWidget(Author) ) class Meta: model = Book fields = ('title', 'author', 'category') # 对应CSV的列名
这样导入CSV时,会自动按作者名不区分大小写查找,找不到就创建新的Author实例。
二、外键关联表DateTime字段的生成
1. 自动生成场景
如果关联表(比如Author)的DateTime字段设置了auto_now_add或auto_now,Django会自动处理时间填充,无需额外代码:
# Author模型示例 from django.db import models class Author(models.Model): name = models.CharField(max_length=100, unique=True) created_at = models.DateTimeField(auto_now_add=True) # 创建时自动填当前时间 updated_at = models.DateTimeField(auto_now=True) # 修改时自动更新时间
2. 自定义时间场景
如果需要从CSV中读取时间值并赋值,可在自定义Widget的clean方法里手动处理:
def clean(self, value, row=None, *args, **kwargs): if not value: return None queryset = self.get_queryset(value, row) if queryset.exists(): return queryset.first() # 从CSV的author_created列读取时间(需确保CSV有对应列) created_time = row.get('author_created') if created_time: from django.utils.dateparse import parse_datetime created_time = parse_datetime(created_time) # 创建时传入自定义时间 return self.model.objects.create( name=value.strip(), created_at=created_time )
三、示例CSV格式
title,author,category Python入门,张三,编程 Django实战,ZHANG SAN,Web开发 Flask教程,李四,编程
导入后,第二行的ZHANG SAN会匹配到第一行创建的张三,不会重复生成作者。
内容的提问来源于stack exchange,提问作者miller
相关产品推荐
相关产品推荐

