Home > OS >  In Django Tables2, how do you make a column show text from a table referenced by a foreign key?
In Django Tables2, how do you make a column show text from a table referenced by a foreign key?

Time:07-01

After reading all the docs and answers I can find, and burning a whole day, I still can't make this work. Using Django Tables2, I want to show a list of instruments; the instruments table includes a foreign key to an instrumentsType table. When I list the instruments and their attributes, I want to use the foreign key to substitute the textual instrument type description from the other table. I have tried every combination of double underscores and other accessor techniques, but so far all I get is the dreaded -- in the column. (Displaying just the record ID works).

from .models import Instrument
from django_tables2 import A
from instrumenttypes.models import InstrumentType

class InstrumentTable(tables.Table):
    id = tables.LinkColumn('instrument_details', args=[A('station_id')])

    class Meta:
        model = Instrument
        template_name = "django_tables2/bootstrap.html"
        fields = ("id", "instrument", "nickname", "serialNo",
           "instrument__instrumenttype_id__instrumenttypes__id_instrumentType" )

The models involved are: Instruments model.py

from django.db import models

from instrumenttypes.models import InstrumentType
from stations.models import Station

# Create your models here.
class Instrument(models.Model):
    instrument = models.CharField(max_length=40)
    instrumenttype = models.ForeignKey(InstrumentType, on_delete=models.CASCADE, null=True)
    station = models.ForeignKey(Station, on_delete=models.CASCADE, default=1)
    serialNo = models.CharField(max_length=60, null=True, blank=True)
    dateAdded = models.DateTimeField("Date Added", null=True, blank=True)
    dateRemoved = models.DateTimeField("Date Removed", null=True, blank=True)
    status = models.CharField(max_length=10, null=True, blank=True)
    nickname = models.CharField(max_length=40, null=True, blank=True)

InstrumentTypes model.py

from django.db  import models

class InstrumentType(models.Model):
    instrumentType = models.CharField(max_length=40)

Resulting output:

ID  Instrument  Nickname    SerialNo    Instrumenttype
4   instr2       nock2       123           —

The most relevant online references I have found are here and here; but having tried the suggestions, no luck. What am I missing?

CodePudding user response:

I've been struggling to get something working too (but I finally did), and I found the examples too brief.

I think you want to get rid of this stuff in the Meta class

"instrument__instrumenttype_id__instrumenttypes__id_instrumentType" 

I think Meta.fields should just be a list of field names, and that you refer to the attribute in the other table from the point of view of the type of object you will later pass in to the IntrumentTable constructor (and that is named in the Meta.model attribute:

from django_tables2.utils import Accessor

    class InstrumentTable(tables.Table):
            instrument_type = tables.Column(accessor=Accessor('instrumenttype.name'))
            
            class Meta:
                model = Instrument
                template_name = "django_tables2/bootstrap.html"
                fields = ("id", "instrument", "nickname", "serialNo", "insrument_type")

Then, in view, make an instance of InstrumentTable

def myview(request):
    table_to_render = InstrumentTable(Instrument.objects)
    return render(request, sometemplate, {table: table_to_render})

You didn't show your view, and I know there may be a different way. If you have the whole thing in a repo somewhere, leave a link.

  • Related