Loose coupling of apps & model inheritance
django, django-models
Solution
I think what you're looking for is the GenericForeignKey from the ContentTypes framework, which is shipped with Django in the contrib package. It handles recording the type and id of the subclass instance, and provides a seamless way to access the subclasses as a foreign key property on the model.
In your case, it would look something like this:
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
class Payment(models.Model):
order_content_type = models.ForeignKey(ContentType)
order_object_id = models.PositiveIntegerField()
order = generic.GenericForeignKey('order_content_type', 'order_object_id')
You don't need to do anything special in order to use this foreign key... the generics handle setting and saving the `order_content_type` and `order_object_id` fields transparently:
s = SpecializedOrder()
p = Payment()
p.order = s
p.save()
Now, when your `Payment` save method runs:
if is_paid:
self.order.order_payment_complete() # self.order will be SpecializedOrder
Problem
I have a design question concerning Django. I am not quite sure how to apply the principle of loose coupling of apps to this specific problem: I have an order-app that manages orders (in an online shop). Within this order-app I have two classes: ``` class Order(models.Model): # some fields def order_payment_complete(self): # do something when payment complete, ie. ship products pass class Payment(models.Model): order = models.ForeignKey(Order) # some more fields def save(self): # determine if payment has been updated to status 'PAID' if is_paid: self.order.order_payment_complete() super(Payment, self).save() ``` Now the actual problem: I have a more specialized app that kind of extends this order. So it adds some more fields to it, etc. Example: ``` class SpecializedOrder(Order): # some more fields def order_payment_complete(self): # here we do some specific stuff pass ``` Now of course the intended behaviour would be as follows: I create a SpecializedOrder, the payment for this order is placed and the `order_payment_complete()` method of the SpecializedOrder is called. However, since Payment is linked to Order, not SpecializedOrder, the `order_payment_complete()` method of the base Order is called. I don't really know the best way to implement such a design. Maybe I am completely off - but I wanted to build this order-app so that I can use it for multiple purposes and wanted to keep it as generic as possible. It would be great if someone could help me out here! Thanks, Nino