2009-04-04 6 views
0

Ich verwende ein Snippet in http://www.djangosnippets.org/snippets/1034/ für meine Modellvererbung. Es funktioniert auf Anhieb. Nachdem ich jedoch einige Elemente in der Datenbank gelöscht habe, funktioniert der Code falsch. Beim Debuggen stellte ich fest, dass das Problem in der Methode resident ist: as_leaf_class. Im folgenden Code:Problem bei der Modellvererbung, wenn einige Elemente gelöscht werden

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

die letzte Zeile wird Ausnahme auslösen, wenn das Element gelöscht. Jeder könnte eine Lösung dafür geben?

Modell Vererbung mit Inhaltstyp und Vererbung-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() 
+0

Bitte sagen Sie uns, welche Ausnahme ausgelöst wird. ObjecNotExist? Ein Stack-Trace könnte helfen. –

Antwort

0

Ich weiß nicht, ob das Snippet jetzt noch relevant ist, dass Sie abstract base classes.

verwenden Auf diese Weise können Sie ein Modell erklären, das ist keine Db-Tabelle, aber andere Modelle können davon erben.

+0

Es gibt immer noch Anwendungsfälle für die tabellenbasierte Modellvererbung (wenn auch nicht sehr viele, wenn Sie mich fragen). –

0

Erste Antwort: Warum versuchen Sie as_leaf_class für ein gelöschtes Objekt aufzurufen? Wenn es schmerzt, wenn du das tust, tu es nicht.

Die zweite Antwort ist, dass Sie die fehlerhafte Zeile mit try ... außer Meal.DoesNotExist verpacken und None oder self oder etwas zurückgeben können.