1

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?

Community
  • 1
  • 1
  • First, you would have to use `'lipids'` in the accessor string. Then, what do you want displayed there? The names of all the `Lipid` instances associated with the organism? – user2390182 Feb 20 '17 at 12:36
  • Thanks @schwobaseggl! I already tried with lower-case lipids (also Lipids, Lipid, lipid) and it is not working either.... And yes, I would like to display all the lipid instances associated to the Organism. – Leonardo Hardtke Feb 20 '17 at 12:42

1 Answers1

1

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.

user2390182
  • 72,016
  • 6
  • 67
  • 89
  • Yes! Great! It worked! Tanks mate! You saved my day! Night actually here in Australia! Really appreciated, now I can go to sleep! – Leonardo Hardtke Feb 20 '17 at 12:56
  • One thing: you can only order the table by non-db-field-columns if your table data is not a queryset, but a python list, so might want to make the column `orderable=False` or turn the queryset into list ;) – user2390182 Feb 20 '17 at 13:03
  • This worked great~ I am wondering though, if i want to add a multi-field filter, what do you suggest? I changed my qs to a list since i need to filter, but then i cannot use django-filter as it seems to only accept a queryset (and it will also not let me filter on this property). Any ideas? – bio_sprite Jun 04 '21 at 05:37