1

Using Django Import/Export, I have problems importing foreign key fields into my Django models. Specifically, I have three fields in my model that I want to import (the fourth one—participant—having a default value, so we can ignore that one), of which one is an IntegerField and the two other are ForeignKey fields.

All three fields are converted to numeric format before importing. However, the ForeignKey fields can't read these values and instead import NaN (presumably because I have set these model fields to null=True.

I have tried multiple of the solutions on similar questions, but they did not solve this problem.

What am I doing wrong here?

models.py

class User(auth.models.User,auth.models.PermissionsMixin):
    def __str__(self):
        return "@{}".format(self.username)

class Forskningsresultater(models.Model):
    id = models.IntegerField(primary_key=True)
    authors = models.ManyToManyField(settings.AUTH_USER_MODEL, through='PersonRes', blank=True,related_name='authors',verbose_name="Authors")
    ... (plus irrelevant fields for this question)

class PersonRes(models.Model):
    id = models.IntegerField(primary_key=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,null=True,verbose_name="user")
    forskningsresultater = models.ForeignKey(Forskningsresultater,on_delete=models.CASCADE, null=True,verbose_name="forskningsresultater")
    participant = models.BooleanField(default=True)
    def __str__(self):
        return "{}. Result {}: {}".format(self.id,self.forskningsresultater, self.user)

admin.py

from import_export import widgets, fields, resources
class PersonResResource(resources.ModelResource):
    user = fields.Field(column_name='user_id', attribute='user', widget=widgets.ForeignKeyWidget(settings.AUTH_USER_MODEL, 'id'))
    forskningsresultater = fields.Field(column_name='forskningsresultater_id', attribute='forskningsresultater', widget=widgets.ForeignKeyWidget(Forskningsresultater, 'id'))
    class Meta:
        model = PersonRes
        fields = ('id','user','forskningsresultater','participant',)

from import_export.admin import ImportExportModelAdmin
class PersonResAdmin(ImportExportModelAdmin):
    class Meta:
        resource_class: PersonResResource
admin.site.register(PersonRes,PersonResAdmin)

myscript.py

...

df_persres[['A']] = df_persres[['A']].apply(pd.to_numeric)
df_persres[['B']] = df_persres[['B']].apply(pd.to_numeric)
df_persres[['C']] = df_persres[['C']].apply(pd.to_numeric)

df_persres.columns =['id','user_id','forskningsresultater_id']

if( len(df_persres.index) != 0):
    import tablib
    from import_export import resources
    from accounts.models import PersonRes
    personres_resource = resources.modelresource_factory(model=PersonRes)()
    antall = len(df_persres.index)
    for row in range(antall):
        dataset = tablib.Dataset([  df_persres.iat[row,0],
                                    df_persres.iat[row,1],
                                    df_persres.iat[row,2]],
                                    headers=['id', 'user_id', 'forskningsresultater_id'])
        result = personres_resource.import_data(dataset, dry_run=True)
else:
    pass

When printing dataset, I get the following (showing only one instance of dataset):

id       |user_id|forskningsresultater_id
---------|-------|-----------------------
148097456|1480974|56

However, when i print the model, using pd.DataFrame.from_records(PersonRes.objects.all().values()), I get:

      forskningsresultater_id           id  participant  user_id
0                         NaN       338884         True      NaN
1                         NaN       566233         True      NaN
2                         NaN       636223         True      NaN

3                         NaN       754756         True      NaN
4                         NaN       802856         True      NaN
5                         NaN      1005256         True      NaN
...
0

1 Answer 1

2

The column names should be as follows (remove the _id):

user = fields.Field(column_name='user', attribute='user', widget=widgets.ForeignKeyWidget(settings.AUTH_USER_MODEL, 'id'))
forskningsresultater = fields.Field(column_name='forskningsresultater', attribute='forskningsresultater', widget=widgets.ForeignKeyWidget(Forskningsresultater, 'id'))
Sign up to request clarification or add additional context in comments.

4 Comments

I tried this already. I did it once more just in case, but it still returns None on both the ForeignKey fields. Do you have another suggestion on what might be wrong in my code?
Do you have the Forskningsresultater and user fields and ID's populated already and you are just importing the join of existing objects in PersonRes?
Are you sure your column headings are also user and forskningsresultater in your file? You set the headers to _id as well
You are absolutely right, Jonathan. I removed all the "_id"s, and it worked. The reason it didn't work earlier, was because of a typo in my code that I haven't posted in my question here on SO. Thank you for your help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.