views:

33

answers:

1

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.

A: 

Try inherit OrderItemInlineAdmin's Form a define your own Form there. But fingers crossed for that.

kvbik