views:

281

answers:

2

Here's the deal:

I got two db models, let's say ShoppingCart and Order. Following the DRY principle I'd like to extract some common props/methods into a shared interface ItemContainer.

Everything went fine till I came across the _flush() method which mainly performs a delete on a related object set.

class Order(models.Model, interface.ItemContainer):

# ...

def _flush(self):
    # ...
    self.orderitem_set.all().delete()

So the question is: how do I dynamically know wheter it is orderitem_set or shoppingcartitem_set?

+2  A: 

First, here are two Django snippets that should be exactly what you're looking for:

Second, you might want to re-think your design and switch to the django.contrib content types framework which has a simple .model_class() method. (The first snippet posted above also uses the content type framework).

Third, you probably don't want to use multiple inheritance in your model class. It shouldn't be needed and I wouldn't be surprised if there were some obscure side affects. Just have interface.ItemContainer inherit from models.Model and then Order inherit from only interface.ItemContainer.

Van Gale
You can actually do multiple inheritance like that and it works without a problem (so far as I can tell), but I would still probably inherit ItemContainer from Model (unless its an interface that can apply to non-Model objects).
Carl Meyer
+2  A: 

You can set the related_name argument of a ForeignKey, so if you want to make minimal changes to your design, you could just have ShoppingCartItem and OrderItem set the same related_name on their ForeignKeys to ShoppingCart and Order, respectively (something like "item_set"):

order = models.ForeignKey(Order, related_name='item_set')

and

cart = models.ForeignKey(ShoppingCart, related_name='item_set')
Carl Meyer