Skip to main content
 首页 » 编程设计

python之在 django-import-export 中处理外键的导入

2025年05月04日30落叶无声

我不明白 django-import-export 模块如何处理外键。 这是一个简单的例子: 模型.py

class TFamilies(models.Model): 
    id_fam = models.AutoField(primary_key=True, unique=True) 
    name_fam = models.CharField(max_length=1024, blank=True,verbose_name='Famille') 
 
 
class TGenus(models.Model): 
    id_genus = models.AutoField(primary_key=True, unique=True) 
    name_genus = models.CharField(max_length=1024,verbose_name='nom de genre') 
    id_fam = models.ForeignKey(TFamilies, null=True, db_column='id_fam', blank=True, verbose_name='Famille') 

我想允许人们添加与家庭相关的属!只有 name_genus 和 name_fam 的 CSV/XLS...(id 留空)。

大部分时间家族已经存在于数据库中,Django juste 必须找到正确的 ID 号......

管理员.py

class TGenusResource(resources.ModelResource): 
 
    name_fam = fields.Field(widget=widgets.ForeignKeyWidget(TFamilies, 'name_fam')) 
 
    class Meta: 
        model = TGenus 
        import_id_fields = ['id_genus'] 
 
 
class TGenusAdmin(ImportExportActionModelAdmin): 
    form = TGenusAdminForm 
    resource_class = TGenusResource 
    pass 

此配置导致导入界面出错:

Line number: 1 - 'NoneType' object has no attribute 'name_fam' 
Traceback (most recent call last): 
File "/....../lib/python2.7/site-packages/import_export/resources.py", line 348, in import_data 
row_result.object_repr = force_text(instance) 
File "......./lib/python2.7/site-packages/django/utils/encoding.py", line 85, in force_text 
s = six.text_type(s) 
AttributeError: 'NoneType' object has no attribute 'name_fam' 

我不明白... 我也尝试在那里回答:django-import-export resource definition for foreignkey field? 有点像那里:Foreign Key in django migration using django-import-export

我必须使用 before_import 吗?找到自己的比赛?

请您参考如下方法:

我发现你必须找到匹配的自己!不可能更改 tablib 数据集中的值,因此您必须对条目进行更改并将它们放回新行,然后删除旧行。

我的 excel 模板包含列 id_genus(空)、name_genus 和 id_fam 填写了家庭名称!

对于登陆这里的任何人,我发布了我的方式:

def before_import(self, dataset, dry_run): 
        """ 
        Make standard corrections to the dataset before displaying to user 
        """ 
 
        i = 0 
        last = dataset.height - 1 
 
        # for all lines, search for id of family given and add a new line at the bottom with it then delete the first one 
        while i <= last: 
            # Check if the Genus exist in DB 
            if (TGenus.objects.filter(name_genus=dataset.get_col(2)[0].capitalize())): 
                id_genus = TGenus.objects.filter(name_genus=dataset.get_col(2)[0].capitalize())[0].id_genus 
            else : 
                id_genus = '' 
            # Check if the family exists in DB 
            try: 
                TFamilies.objects.get(name_fam=dataset.get_col(2)[0].capitalize()) 
            except TFamilies.DoesNotExist: 
                raise Exception("Family not in DB !")                    
            except TFamilies.MultipleObjectsReturned: 
                pass 
 
            # use of "filter" instead of "get" to prevent duplicate values, select the first one in all cases 
            dataset.rpush((id_genus, 
                dataset.get_col(1)[0], 
                TFamilies.objects.filter(name_fam=dataset.get_col(2)[0].capitalize())[0].id_fam)) 
            dataset.lpop() 
            i = i + 1 

我的 django 管理员可以由非系统管理员使用,因此,他们可以复制不在数据库中的属或科... 如果有人有更好地处理错误的想法,我想阅读它! 另外,我想在预览中保留家人的名字,而不仅仅是她的身份证……如果你知道怎么做,我已经发布了另一个问题:Is-it possible to customize the template of preview in django import-export?