Search code examples
djangodjango-modelsdjango-nonrel

Correctly accessing derived class in OneToOneField relation in Django-Nonrel


I'm pulling my hair out trying to solve this (hopefully) simple problem.

I am using Django-nonrel, and I am trying to setup a few models. I've simplified the code below:

class Application(models.Model)
    name = "Application"

    def get_name(self):
        print(self.name)

class ExampleApp(Application)
    name = "Example Application"

class Site(models.Model)
    app = models.OneToOneField(Application, null=True)
    id  = models.CharField(max_length=1)
    # other details not important

When I obtain an instance of Site, I would like to obtain an instance of the derived class (e.g. ExampleApp)

class MyView(View):
    def get(self, request, *args, **kwargs):
        # Presuppose that I have an object with id="a"
        site = Site.objects.filter(id="a")

        #<Application: Application>
        app = site.app

        #returns "Application", not "Example Application"
        app.get_name()

How can I access the derived class?

(Ideally, I would like Application to be an abstract base class, but django does not allow relationships to abstract base classes. I would define fields inside Application, but django-nonrel does not support multi-table inheritance.)


Solution

  • What Furbeenator answered is correct, but I feel that my (self-)answer could be more valuable to anyone in my situation.

    Django-nonrel includes a few nice apps, notable djangotoolbox. Included in djangotoolbox is a particular field, EmbeddedModelField. It appears to store a copy of a model as a blob in the 'container' model.

    In my example:

    from djangotoolbox.fields import EmbeddedModelField
    
    class Site(models.Model)
        app = EmbeddedModelField(null=True)
        id  = models.CharField(max_length=1)
        # other details not important
    

    The upside to this is that, in my circumstances, it also meant that I could make my Application class abstract. The downside is that the data is now duplicated, and I still cannot access the Site instance from the Application instance (but in my case, that was an acceptable tradeoff).