django-import-export导入外键字段的问题

Django-import-export problem importing foreignkey field

我在 Django(版本 3.1.4)中使用 Django-import-export(版本 2.5.0)模块。所以我能够导入除 ForeignKey 字段之外的所有模型字段。我不知道如何使这个工作。你能看看我的代码,看看有什么问题或需要更改吗?我需要 Django Admin 来导入 ForeignKey 字段。

models.py

# myapp
from django.db import models
from django.contrib.auth.models import User 

class Agency(models.Model):
    system_name = models.CharField(max_length=255)
    county = models.CharField(max_length=60)
    state = models.CharField(max_length=2)
    active = models.BooleanField(default=True)
    system_no = models.CharField(max_length=7, unique=True)
    
    def __str__(self):
        return self.system_no
    
class SitePart(models.Model):
    # I tried changing the "system_no" to another name "agency_no" through out the *.py's this did not resolve the problem. Maybe I missed something.
    system_no = models.ForeignKey('Agency', on_delete=models.CASCADE, to_field='system_no', null=True, blank=True)
    part_name = models.CharField(max_length=125) 
    status_tuple = [('AB','Abandoned'),('AC','Active Compliant'),('DS','Destroyed'),('IA','Inactive'),
            ('SB','Stand By waiting acitvation'),('MO','Monitoring')]
    status = models.CharField(max_length=2, choices=status_tuple, default= 'SB')
    # sys_site_n is unique
    sys_site_n = models.CharField(max_length=15, unique=True)

    def __str__(self):
        return self.part_name

resources.py

from import_export import fields, resources, widgets
from import_export.widgets import ForeignKeyWidget
from myapp.models import Agency, SitePart
 
class AgencyResource(resources.ModelResource):
    class Meta:
        model = Agency
        import_id_fields = ('system_no',)
        fields = ('system_name', 'county', 'state', 'active', 'system_no',)
        

class SitePartResource(resources.ModelResource):
    system_no = fields.Field(
        column_name='system_no',
        attribute='system_no',
        widget=ForeignKeyWidget(Agency,'system_no'))
    print(system_no)    
    
    class Meta:
        model = SitePart
        import_id_fields = ('sys_site_n',)
        fields = ('system_no','part_name','status', 'sys_site_n',)

admin.py

from django.contrib import admin
from import_export.admin import ImportExportModelAdmin
from myapp.resources import AgencyResource, SitePartResource
from myapp.models import (Agency, County, SitePart)

class AgencyAdmin(ImportExportModelAdmin):
    resource_class = AgencyResource
    list_display = ('system_name', 'county', 'state', 'active', 'system_no',)

class SitePartAdmin(ImportExportModelAdmin):
    list_display = ('system_no', 'part_name', 'status', 'sys_site_n',)
    search_fields = ['system_no',] # Tried removing this, didn't work
    resource_class = SitePartResource

admin.site.register(Agency, AgencyAdmin)
admin.site.register(County)
admin.site.register(SitePart, SitePartAdmin)

代理商Table

system_name county state active system_no
MAGNA SCHOOL INYO CA 1 1300553
PINE SCHOOL INYO CA 1 1300560

站点部分Table

system_no part_name status sys_site_n
1300553 MAGNA SCHOOL AC 1300553-01
1300553 Backup Genrtor SB 1300553-02
1300560 PINE SCHOOL AC 1300560-01
1300560 Backup Genrtor SB 1300560-02

当我在 django admin 中导入时,system_no 是空的。

我没有能够添加评论的信誉点数,但我认为您遇到的问题是由于您的模型的字段命名约定所致。

由于 SitePartAgency 中的外键关系称为 system_no,因此您的 SitePartResource 的外键小部件未引用正确的字段 - 它是引用相关的 Agency 模型实例(我相信这就是为什么您在导入时没有收到任何错误但未显示该值的原因)。

要解决此问题,您只需更改 ForeignKey 小部件以引用相关 Agency 对象的 system_no 字段(而不是实例本身)。我还没有测试过,但将您的 FK 字段更改为类似以下内容应该会起作用!

#resources.py
class SitePartResource(resources.ModelResource):
    ...

    system_no = fields.Field(
        column_name='system_no',
        attribute='system_no',
        widget=ForeignKeyWidget(
            Agency,
            field='system_no__system_no'
        )
    )
    
    ...
    

编辑:

#resources.py
class SitePartResource(resources.ModelResource):
    class AgencyForeignKeyWiget(ForeignKeyWidget):
        def get_queryset(self, value, row):
            return self.model.objects.filter(
                system_no__exact=row["system_no"],
            )

    system_no = fields.Field(
        column_name='system_no',
        attribute='system_no',
        widget=AgencyForeignKeyWidget(
            Agency,
            field='system_no'
        )
    )
    
    part_name = fields.Field(column_name="part_name", attribute="part_name")
    status = fields.Field(column_name="part_name", attribute="part_name")
    sys_site_n = fields.Field(column_name="system_site_n", attribute="system_site_n")

    class Meta:
        model = SitePart
        import_id_fields = ("system_no", "system_site_n")
        fields = ('system_no','part_name','status', 'sys_site_n',)