Search code examples
pythondjangodjango-tables2

django-tables 2 M2M field not shown


I am trying to show a M2M field in a django-table2 as seen in Django-tables2: How to use accessor to bring in foreign columns? and Accessing related models with django-tables2

Using: foreigncolumn = tables.Column(accessor='foreignmodel.foreigncolumnname'), I only see a '--'...

# The models:

class Organism(models.Model):
        species_name = models.CharField(max_length=200)
        strain_name = models.CharField(max_length=200)
        eukaryotic = models.BooleanField(default=True)
        lipids = models.ManyToManyField('Lipid',blank=True)

class Lipid(models.Model):
    lm_id = models.CharField(max_length=100)
    common_name = models.CharField(max_length=100,blank=True)
    category = models.CharField(max_length=100,blank=True)

#The tables

class OrganismTable(tables.Table):
    name  = tables.LinkColumn('catalog:organism-detail', text=lambda record: record.species_name, args=[A('pk')])
    lp = tables.Column(accessor='Lipid.common_name')
    class Meta:
        model = Organism
        sequence = ['name','lp']
        exclude = ['id','species_name']

Any idea what I'm doing wrong?


Solution

  • This does not work so easily for ManyToManyFields because of the simple way Accessor works. You could display the repr of the related QuerySet via 'lipids.all' but that does not seem sufficient here. You can, however, add a property (or method) to your Organism model and use it in the accessor. This way, you can display any custom information related to the instance:

    class Organism(models.Model):
        # ...
        @property
        def lipid_names(self):
            return ', '.join(l.common_name for l in self.lipids.all())  # or similar
    
    class OrganismTable(tables.Table):
        # ...
        lp = tables.Column(accessor='lipid_names')
    

    I would recommend then to add a prefetch_related('lipids') to the Organism QuerySet that you pass to the table for better performance.