2016-03-20 6 views
0

Ich habe eine folgende Klasse (andere Felder sind trivial (Autor, etc), so weggelassen).Django rekursive Beziehung: Wie Objekt aus Manager-Objekt zu entfernen

class Article(models.Model): 

origin = models.ForeignKey('self', null=True, related_name="%(app_label)s_%(class)s_revision") 

Ich möchte alle Revisionen eines Artikels speichern, in a.website_article_revision Liste. Wenn nach I add eine Revision zu dieser Liste, wie diese a.website_article_revision.add(rev) wird automatisch hinzugefügt, um die Article.objects Manager und dies kann verstanden werden, da das Revisionsobjekt selbst eine Artikelinstanz ist. Aber ich will keine Revision im Manager-Objekt, nur in einem Listenattribut eines Artikelobjekts a.website_article_revision erscheinen.

P.S. Ich möchte wirklich keine Unterklasse erstellen.

+0

Können Sie den letzten Satz umformulieren? – v1k45

+0

@ v1k45, wenn was ich will, ist unmöglich, dann muss ich dieses Artikelmodell, für Revisionen Unterklasse. Ich wollte nur eleganten und kleinen Code schreiben, wenn es überhaupt möglich ist. –

+0

Tut mir leid, ich habe Sie verwirrt, ich fragte nach dieser Zeile _Aber ich möchte keine Revision im Manager-Objekt erscheinen ...._ – v1k45

Antwort

0

Klingt wie ein Job für custom managers:

class ArticleManager(models.Manager): 
    def get_queryset(self): 
     return super(ArticleManager, self).get_queryset().filter(origin=None) 

class Article(models.Model): 
    objects = ArticleManager() 
    origin = models.ForeignKey('self', null=True, related_name="%(app_label)s_%(class)s_revision") 

Dies wird die Standard objects Manager in Ihrem Article Modell ersetzen und Article.objects.all() alle Artikel zurück, die origin ist null ist.

Ich gehe davon aus, dass überprüft, ob origin is None ist, wie Sie feststellen möchten, ob ein bestimmtes Artikelobjekt keine Revision ist.

BEARBEITEN: Möglicherweise möchten Sie den Ursprung ForeignKey zu einem OneToOneField ändern. Schließlich kann ein Artikel nur eine Revision haben, und diese Revision kann eine andere Revision haben, und so weiter.

+0

Klingt wie eine Lösung für mich. Ich fürchte nur, Filterung wird zu viel Server-Ressourcen verbrauchen und vielleicht sollte ich ein paar Dutzend Zeilen Code schreiben. Was ist wichtiger Länge oder Leistung (Annahme einer hypothetischen Website mit 100K Artikeln). –

+0

@ Koala-Lava Ehrlich gesagt, würde ich diese Lösung versuchen, bevor Sie Ihr Artikelmodell untergliedern. Mit dieser Lösung haben Sie eine nette "Kette" von Artikeln, von denen jeder auf seinen Nachfolger verweist. Wenn Sie eine Unterklasse erstellen, müssen Sie die erste Version des Artikels in der Article-Tabelle behalten und die Revisionen in eine eigene Tabelle einfügen. Sie müssen diese Tabelle nach Datum sortieren, um den letzten zu finden. Außerdem wird Django mindestens 1 Join machen, um herauszufinden, ob ein Artikel Revisionen hat oder nicht. Mit dieser Lösung werden keine Joins benötigt, weil Sie nur überprüfen, ob der Fremdschlüssel null ist. –

0

Wenn Sie nicht selbst Ihre Revisionen zu modellieren, ist es django-reversion, die die Arbeit für Sie tut:

django-Reversion ist eine Erweiterung Rahmen Django Web, die Einrichtungen umfassende Versionskontrolle bietet .

Es ist ordnungsgemäß dokumentiert.