views:

161

answers:

2

I use a snippet in http://www.djangosnippets.org/snippets/1034/ for my Model inheritance. It works fine at the first. However, after I delete some elements in database, the code works wrong. As I debug, I found that the problem is reside in the method: as_leaf_class. In the following code:

if (model == Meal):
    return self
return model.objects.get(id=self.id)

the last line will raise exception when the element is deleted. Anyone could give a solution for this?

Model inheritance with content type and inheritance-aware manager

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.db.models.query import QuerySet

class SubclassingQuerySet(QuerySet):
    def __getitem__(self, k):
        result = super(SubclassingQuerySet, self).__getitem__(k)
        if isinstance(result, models.Model) :
            return result.as_leaf_class()
        else :
            return result
    def __iter__(self):
        for item in super(SubclassingQuerySet, self).__iter__():
            yield item.as_leaf_class()

class MealManager(models.Manager):
    def get_query_set(self):
        return SubclassingQuerySet(self.model)

class Meal (models.Model) :
    name = models.TextField(max_length=100)
    content_type = models.ForeignKey(ContentType,editable=False,null=True)
    objects = MealManager()

    def save(self, *args, **kwargs):
        if(not self.content_type):
            self.content_type = ContentType.objects.get_for_model(self.__class__)
            super(Meal, self).save(*args, **kwargs)

    def as_leaf_class(self):
        content_type = self.content_type
        model = content_type.model_class()
        if (model == Meal):
            return self
        return model.objects.get(id=self.id)

class Salad (Meal) :
    too_leafy = models.BooleanField(default=False)
    objects = MealManager()
A: 

I don't know if that snippet is still relevant now that you can use abstract base classes.

This lets you declare a model that is not a db table but that other models can inherit from.

Jason Christa
There are still use cases for table-based model inheritance (though not very many, if you ask me).
Carl Meyer
A: 

First answer: Why are you trying to call as_leaf_class on a deleted object? If it hurts when you do that, don't do it.

The second answer is that you could wrap the failing line with try...except Meal.DoesNotExist, and return None or self or something.

Carl Meyer