Search code examples
djangodjango-import-export

Exporting and Importing a foreign key field that has a many-to-many relationship in Django


I've got a complicated relationship between my Django models and I'm trying to get django-import-export to play nicely.

class Person(models.Model):
    name = models.CharField(max_length=64)

class Team(models.Model):
    rep = models.ManyToManyField(Person, related_name="rep")
    
    def get_reps(self):
        return "/".join(sorted([p.name for p in self.reps.all()]))

class Account(models.Model):
   tid = models.IntegerField("Territory ID", primary_key=True)
   name = models.CharField("Territory Name", max_length=64)
   sales_team = models.ForeignKey(Team, related_name="sales_team")

I'm trying to export (and hopefully later import) the territories with the names of the reps as rendered by the get_reps method.

class TerritoryResource(resources.ModelResource):
    tid = fields.Field(attribute='tid', column_name="Territory ID")
    name = fields.Field(attribute='name', column_name="Territory Name")
    sales_team = fields.Field(
        column_name="Sales Team",
        widget=widgets.ForeignKeyWidget(Team, "get_reps")
    )

The export is giving me a blank field. If I don't use the widget I get the Team ID as I'd expect.

Is it possible to get my custom name in the export?


Solution

  • I didn't include the standard __str__ methods in the sample code, because I didn't think they were important, but I did have in my Team class definition:

    def __str__(self):
        return self.get_reps()
    

    This means, had I read the documentation with a little more creativity, I would have figured out how to do this. It's deceptively simple:

    class TerritoryResource(resources.ModelResource):
        ...
    
        def dehydrate_sales_team(self, territory):
            return str(territory.sales_team)
    

    I could also use return territory.sales_team.get_reps() to get the same results.