Josh Dwernychuk
Josh Dwernychuk

Reputation: 105

Django models: Inherit from variable abstract base class

I'm hoping to inherit to a child class from a variable abstract base class. So a child class would not have to inherit from a pre-defined base class and would instead be able to inherit from any one class of multiple base classes. Ideally, the models would be setup like so:

class Orders(models.Model):
    order_number = models.IntegerField()
    # Orders metrics
    class Meta:
        abstract = True


class Fees(models.Model):
    fee_number = models.IntegerField()
    # Fee metrics
    class Meta:
        abstract = True


class Transactions(Inherit from either Orders or Fees):
    transaction_number = models.IntegerField()
    # Transaction metrics

Transactions would be able to inherit from either orders or fees as they could both be a source of a transaction. Generic foreign keys could be implemented to allow for variable foreign key reference within the Orders model and Fees model but I am curious if there is a way to do this without using generic foreign keys. Is there a specific arrangement, mixin, decorator, property, or method that will allow for association of a child class with a variable abstract parent class?

Upvotes: 1

Views: 705

Answers (2)

DBrowne
DBrowne

Reputation: 723

No you can't do this. Django models can't be modified like this during runtime (after django is intialized). Anyway, this is not a good design pattern. You're confusing composition and inheritance. A Transaction is not a type of Fee or a type of Order so it makes no sense to subclass like this.

You can solve your problem without a generic foreign key by just using two separate ForeignKey fields:

class Transactions(models.Model):
    transaction_number = models.IntegerField()
    order = models.ForeignKey(Orders, null=True, blank=True)
    fee = models.ForeignKey(Fees, null=True, blank=True)

You can then query the different transaction types like this:

fee_payments = Transactions.objects.exclude(fee=None)
order_payments = Transaction.objects.exclude(order=None)

Upvotes: 0

Astik Anand
Astik Anand

Reputation: 13057

This is not possible. But what you want can be easily achieved by creating ForeignKey realtionships from Transaction to both Fees and Order.

Upvotes: 1

Related Questions