2

I have a model Property with certain fields and a relevant method:

class Property(models.Model):
    table = models.ForeignKey(Table)
    field1 = models.CharField()
    field2 = models.IntegerField()
    field3 = models.BooleanField()

    class Meta:
        abstract = True

    def post():
        pass

But then I have a definite number of types of columns, conceptually speaking. There is no difference in the fields, only in how the behavior of a certain method is implemented:

class Property1(Property):
    def post():
        # execute behavior for Property1
        pass

class Property2(Property):
    def post():
        # execute behavior for Property2
        pass

and so on.

If I turned Property into an abstract base model class and have the rest inherit it, I will end up with different tables for each property. I am not sure I want that. All tables will look the same, which is redundant.

But at the same time when running a query to get all properties in a table and calling post() I want the corresponding behavior to be executed:

for prop in table.property_set.all():
    prop.post()

What are my options?

dabadaba
  • 9,064
  • 21
  • 85
  • 155

1 Answers1

3

For that, you can use proxy model. Try like this:

class Property(models.Model):
    table = models.ForeignKey(Table)
    field1 = models.CharField()
    field2 = models.IntegerField()
    field3 = models.BooleanField()


class Property1(Property):
    class Meta:
       proxy = True

    def post():
        # execute behavior for Property1
        pass

class Property2(Property):

    class Meta:
       proxy = True

    def post():
        # execute behavior for Property2
        pass

As per documentation:

The MyPerson class operates on the same database table as its parent Person class. In particular, any new instances of Person will also be accessible through MyPerson, and vice-versa:

So you can get the proxy instances like this:

Property1.objects.filter(pk__in=table.property_set.all())
ruddra
  • 50,746
  • 7
  • 78
  • 101
  • That is missing the last requirement I mentioned which is that the appropriate instances of each subclass would be returned instead of the base class. – dabadaba Dec 19 '18 at 10:39
  • @dabadaba please see my updated answer. hope it helps. – ruddra Dec 19 '18 at 11:06
  • That doesn't really help. All that does is force cast all table properties into the given subclass, no matter if it was an instance of that subclass to begin with. – dabadaba Dec 19 '18 at 11:07
  • maybe you can look into this answer: https://stackoverflow.com/questions/3891880/django-proxy-model-and-foreignkey – ruddra Dec 19 '18 at 11:09