10

I'm trying to import data to one of my models, but it's failing because I'm trying to upload the foreignKey Id, not the iterated number that import-export creates.

models.py

from django.db import models
from import_export import resources


class School(models.Model):
    name = models.CharField(max_length=100)
    slug = models.CharField(max_length=100)
    school_id = models.IntegerField(unique=True)

class Sol(models.Model):
    school_id = models.ForeignKey(School, to_field='school_id')
    name = models.CharField(max_length = 100)
    Al1EOC = models.DecimalField(max_digits=5, decimal_places=2)
    AL2EOC = models.DecimalField(max_digits=5, decimal_places=2)

#Class for django-import-export
class SolResource(resources.ModelResource):
    class Meta:
        model = Sol

My admin.py

from import_export.admin import ImportExportModelAdmin


class SolAdmin(ImportExportModelAdmin):
    list_display = ('name', 'school_id')
    resources_class = SolResource
    pass

admin.site.register(Sol, SolAdmin)

My data.csv

id, name, school_id, Al1EOC, AL2EOC
,'Main st school', 1238008, 12.9, 14.9

When I export the data from the SOL model, I get an iterated number for the school ID. I want the actual School ID - the one that holds the foreignKey relationship. And, subsequently, I need to upload data with that foreignKey number. I know the ForeignKey widget is the way to do it, but I don;t understand how it is implemented.

lightstrike
  • 407
  • 4
  • 11
JonnyD
  • 487
  • 2
  • 7
  • 19

3 Answers3

10

There is ForeignKeyWidget in the documentation. You can use it here. There are also IntegerWidget and DecimalWidget.

from import_export.admin import ImportExportModelAdmin

class SolResource(resources.ModelResource):
    school_id = fields.Field(
        column_name='school_id',
        attribute='school_id',
        widget=ForeignKeyWidget(School, 'name'))

    class Meta:
        model = Sol

class SolAdmin(ImportExportModelAdmin):
    list_display = ('name', 'school_id')
    resources_class = SolResource

admin.site.register(Sol, SolAdmin)

This is a working example. Hope it will help.

Jay Modi
  • 3,161
  • 4
  • 35
  • 52
  • Can you explain what this eample does? – All Day Jul 26 '17 at 13:09
  • Widget for a ForeignKey field which looks up a related model using “natural keys” in both export an import. The lookup field defaults to using the primary key (pk) as lookup criterion but can be customized to use any field on the related model. In my example I have used school.name instead of school.pk . – Jay Modi Jul 26 '17 at 13:15
  • Thanks, i just get an error on 'fields' in the first line of the class – All Day Jul 26 '17 at 13:21
  • @JayModi can you help me to understand what does 'school_id' represent with column_name in your suggested code `school_id = fields.Field( column_name='school_id', attribute='school_id', widget=ForeignKeyWidget(School, 'name'))` – Raju Singh Nov 16 '18 at 07:54
4

i think it will help:

class SolResource(resources.ModelResource):
    school_id = fields.Field()

    class Meta:
        # ...

    def dehydrate_school_id(self, sol):
        return sol.school_id.school_id # You can get all fields of related model. This is example.
makketagg
  • 216
  • 1
  • 4
3

Use the widget- works great.

school_id = fields.Field(column_name='school_id', attribute='Sol', widget=widgets.ForeignKeyWidget(Sol, 'school_id'))

Ycon
  • 1,830
  • 3
  • 27
  • 56