Hi, I am trying to solve problem related to model inheritance in Django. I have four relevant models: Order
, OrderItem
which has ForeignKey to Order
and then there is Orderable
model which is model inheritance superclass to children models like Fee
, RentedProduct
etc. In python, it goes like this (posting only relevant parts):
class Orderable(models.Model):
real_content_type = models.ForeignKey(ContentType, editable=False)
objects = OrderableManager()
available_types = []
def save(self, *args, **kwargs):
"""
Saves instance and stores information about concrete class.
"""
self.real_content_type = ContentType.objects.get_for_model(type(self))
super(Orderable, self).save(*args, **kwargs)
def cast(self):
"""
Casts instance to the most concrete class in inheritance hierarchy possible.
"""
return self.real_content_type.get_object_for_this_type(pk=self.pk)
@staticmethod
def register_type(type):
Orderable.available_types.append(type)
@staticmethod
def get_types():
return Orderable.available_types
class RentedProduct(Orderable):
"""
Represent a product which is rented to be part of an order
"""
start_at = models.ForeignKey(Storage, related_name='starting_products',
verbose_name=_('Start at'))
real_start_at = models.ForeignKey(Storage, null=True,
related_name='real_starting_products', verbose_name=_('Real start at'))
finish_at = models.ForeignKey(Storage, related_name='finishing_products',
verbose_name=_('Finish at'))
real_finish_at = models.ForeignKey(Storage, null=True,
related_name='real_finishing_products', verbose_name=_('Real finish at'))
target = models.ForeignKey(Product, verbose_name=_('Product'))
Orderable.register_type(RentedProduct)
class OrderItem(BaseItem):
unit_price = models.DecimalField(max_digits=8, decimal_places=2,
verbose_name=_('Unit price'))
count = models.PositiveIntegerField(default=0, verbose_name=_('Count'))
order = models.ForeignKey('Order', related_name='items',
verbose_name=_('Order'))
discounts = models.ManyToManyField(DiscountDescription,
related_name='order_items', through=OrderItemDiscounts, blank=True,
verbose_name=_('Discounts'))
target = models.ForeignKey(Orderable, related_name='ordered_items',
verbose_name=_('Target'))
class Meta:
unique_together = ('order', 'target')
I would like to have an inline tied to Order model to enable editing OrderItems. Problem is, that the target field in OrderItem points to Orderable (not the concrete class which one can get by calling Orderable's cast
method) and the form in inline is therefore not complete.
Does anyone have an idea, how to create at least a bit user-friendly interface for this? Can it be solved by Django admin inlines only, or you would suggest creating special user interface?
Thanks in advance for any tips.