Search code examples
djangoclassdjango-modelsdjango-model-field

Django Abstract Class change behaviour according to actual class


I think following code explains what I'm trying to do

from django.db import models


class MyBaseClass(models.Model):
    type = models.IntegerField()

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        self.type = #What Should I write here?#
        self.type = self.class.type ?
        super().save(*args, **kwargs)


class Model1(MyBaseClass):
    TYPE = 1


class Model2(MyBaseClass):
    TYPE = 2

I want to make sure following assertions work:

instance1 = Model1.objects.create()
assert(instance1.type, 1)
instance2 = Model2.objects.create()
assert(instance1.type, 2)

How can I make this work? Thanks.


Solution

  • Setting the default value of inherited models

    If you want to set the default of the inherited models, you can monkey patch these. Like:

    class Model1(MyBaseClass):
        TYPE = 1
    
    
    class Model2(MyBaseClass):
        TYPE = 2
    
    Model1._meta.get_field('type').default = Model1.TYPE
    Model2._meta.get_field('type').default = Model2.TYPE

    Adding a static attribute to the models

    In case the .type of all Model1 objects is always 1, and for Model2 objects it is always 2, then there is no reason at all to store these types in the database. These models are stored in different tables, hence the fact that a record originates from the app_model1 table "implies" that. In that case, you thus can set a class attribute, like:

    class MyBaseClass(models.Model):
        type = None
    
        class Meta:
            abstract = True
    
    
    class Model1(MyBaseClass):
        type = 1
    
    
    class Model2(MyBaseClass):
        type = 2