Search code examples
pythondjangotemplatesinheritance

Python Django access fields from inherited model


Hi I have a question related to model inheritance and accessing the fields in a Django template.

My Model:

class Security(models.Model):
    name = models.CharField(max_length=100, blank=False)

class Stock(Security):
    wkn = models.CharField(max_length=15)
    isin = models.CharField(max_length=25)

class Asset(models.Model):
    security = models.ForeignKey(Security, on_delete=models.CASCADE,blank=False)

My views.py

context["assets"] = Asset.objects.all()

My template:

{% for asset in assets %}
   {{ asset.security.wkn }}
...

This gives me an error as wkn is no field of security. Any idea how I can solve this?

Thanks in advance!


Solution

  • Django does not support polymorphism out of the box: even if you use inheritance and you retrieve an item from the database that is a Stock, if you query through Security, you retrieve it as a Security object, so without the specific Stock fields.

    Inheritance and polymorphism are often a pain in relational databases, and therefore it is often something you should not do, unless there are very good reasons to do so.

    In this case, you can fetch it with:

    {{ asset.security.stock.wkn }}

    But this will thus make extra queries, and generate an N+1 problem.

    You can work with django-polymorphic [readthedocs.io] where you can subclass from PolymorphicModel. Queries will then walk down the class hierarchy and add a lot of extra LEFT OUTER JOINs to the database, and then based on the data it receives generate a Stock or a Security object. But as you probably understand, this querying generates a lot of extra work for the database and for Python. Furthermore it makes behavior less predictable, and constraints less easy to enfroce.