使用django-import-export遇get()返回多个GLAccount错误求解决
解决django-import-export导入时
get()返回多个GLAccount的问题 这个问题我之前处理过,核心原因是你的GLAccount采用了code + chart_of_accounts的组合唯一约束,但默认的ForeignKeyWidget只会根据code单字段去查找,当同一个科目代码存在于不同公司的科目表下时,就会匹配到多个实例,触发MultipleObjectsReturned异常。
下面是具体的解决方案:
1. 自定义ForeignKeyWidget
我们需要写一个自定义的Widget,让它在查找GLAccount时,结合当前行对应的公司关联的科目表来过滤结果,确保只返回唯一的实例:
from import_export.widgets import ForeignKeyWidget from . import models class GLAccountForeignKeyWidget(ForeignKeyWidget): def clean(self, value, row=None, *args, **kwargs): # 先从导入行中获取公司代码,找到对应的Company实例 company_code = row.get(self.resource.fields['company'].column_name) company = models.Company.objects.get(code=company_code) # 结合公司的科目表和科目代码,精准查找唯一的GLAccount return self.get_queryset(value, row, *args, **kwargs).get( code=value, chart_of_accounts=company.chart_of_accounts )
2. 替换Resource中的gl_account字段Widget
把原来CompanyAccountResource里的gl_account字段的Widget换成我们刚定义的:
class CompanyAccountResource(ModelResource): class Meta: model = models.CompanyAccount fields = ('company', 'gl_account',) exclude = ('id',) import_id_fields = ('company', 'gl_account',) skip_unchanged = False report_skipped = False company = Field( column_name=Meta.model._meta.get_field('company').verbose_name, attribute='company', widget=ForeignKeyWidget(models.Company, field='code') ) gl_account = Field( column_name=Meta.model._meta.get_field('gl_account').verbose_name, attribute='gl_account', # 替换为自定义Widget widget=GLAccountForeignKeyWidget(models.GLAccount) ) def get_export_order(self): export_fields = ['company', 'gl_account', ] return export_fields
关键细节说明
- 自定义Widget的
clean方法中,我们通过row.get(...)获取导入行中的公司代码,这里用self.resource.fields['company'].column_name来动态获取列名,比硬编码更灵活,避免后续列名修改出问题。 - 利用
Company实例关联的chart_of_accounts,加上导入的科目代码,双条件查找GLAccount,完美匹配你的unique_together约束,确保只会返回一个实例。 - 如果导入数据中存在某个公司+科目代码的组合不存在对应的
GLAccount,会触发DoesNotExist异常,你可以根据需求在自定义Widget中添加异常处理逻辑(比如创建新实例或者跳过该行)。
内容的提问来源于stack exchange,提问作者B_MoSsen
相关产品推荐
相关产品推荐

