Reputation: 2293
I am using the Django-import-export(version 2.5.0) module in Django(version 3.1.4). So I am able to import all my models fields except for the ForeignKey field. I don't know how to make this one work. Can you look at my code and see what is wrong or needs to change? I need Django Admin to import the ForeignKey field.
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)
Agency Table
system_name | county | state | active | system_no |
---|---|---|---|---|
MAGNA SCHOOL | INYO | CA | 1 | 1300553 |
PINE SCHOOL | INYO | CA | 1 | 1300560 |
SitePart 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 |
When I do import in django admin the system_no is empty.
Upvotes: 0
Views: 1818
Reputation: 96
I don't have the reputation points to be able to add a comment but I think the issue you're experencing is due to your model's field naming conventions.
Since your foreign key relation inside the SitePart
to Agency
is called system_no
, your SitePartResource
's ForeignKey Widget isn't referencing the correct field - it's referencing the related Agency
model instance (which I believe is why you aren't getting any errors on import but the value is not being displayed).
To fix this, you just neeed to change the ForeignKey widget to reference the related Agency object's system_no
field (not the instance itself). I haven't tested it but changing your FK field to something like the following should work!
#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'
)
)
...
EDIT:
#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',)
Upvotes: 2