Ich frage mich, ob es möglich war (und wenn ja, wie), mehrere Manager miteinander zu verketten, um einen Abfragesatz zu erstellen, der von den beiden einzelnen Managern beeinflusst wird. Ich werde das spezifische Beispiel erklären, an dem ich arbeite:Django Manager Verkettung
Ich habe mehrere abstrakte Modellklassen, die ich verwenden, um kleine, spezifische Funktionalität für andere Modelle bereitzustellen. Zwei dieser Modelle sind DeleteMixin und GlobalMixin.
Die DeleteMixin wird als solche definiert:
class DeleteMixin(models.Model):
deleted = models.BooleanField(default=False)
objects = DeleteManager()
class Meta:
abstract = True
def delete(self):
self.deleted = True
self.save()
Grundsätzlich bietet es sich um eine pseudo-gelöscht (der gelöschte Flag), anstatt das Objekt tatsächlich gelöscht wird.
Die GlobalMixin wird als solche definiert:
class GlobalMixin(models.Model):
is_global = models.BooleanField(default=True)
objects = GlobalManager()
class Meta:
abstract = True
Es ermöglicht jedes Objekt entweder als globales Objekt oder ein privates Objekt (wie eine öffentliche/private Blog-Post) definiert werden.
Beide haben ihre eigenen Manager, die sich auf das zurückgegebene Abfrage-Set auswirken. Mein DeleteManager filtert das Abfrage-Set, um nur Ergebnisse zurückzugeben, bei denen das gelöschte Flag auf False gesetzt ist, während der GlobalManager das Abfrage-Set so filtert, dass nur Ergebnisse zurückgegeben werden, die als global markiert sind. Hier ist die Erklärung für beide:
class DeleteManager(models.Manager):
def get_query_set(self):
return super(DeleteManager, self).get_query_set().filter(deleted=False)
class GlobalManager(models.Manager):
def globals(self):
return self.get_query_set().filter(is_global=1)
Die gewünschte Funktionalität wäre ein Modell haben beide dieser abstrakten Modelle erweitern und die Fähigkeit zu gewähren, um nur die Ergebnisse angezeigt, die sowohl nicht-gelöscht und global sind. Ich führte einen Testfall auf einem Modell mit 4 Instanzen durch: eine war global und nicht gelöscht, eine war global und gelöscht, eine war nicht-global und nicht-gelöscht, und eine war nicht-global und gelöscht. Wenn ich versuche, Ergebnismengen als solche zu erhalten: SomeModel.objects.all(), bekomme ich Instanz 1 und 3 (die zwei nicht gelöschten - großartig!). Wenn ich SomeModel.objects.globals() ausprobiere, erhalte ich den Fehler, dass DeleteManager keine Globals hat (vorausgesetzt, dass meine Model-Deklaration wie folgt lautet: SomeModel (DeleteMixin, GlobalMixin). Wenn ich die Order umspringe, t bekomme den Fehler, aber filtert die gelöschten nicht heraus). Wenn ich GlobalMixin ändere, um GlobalManager an Globals anstelle von Objekten anzuhängen (also wäre der neue Befehl SomeModel.globals.globals()), erhalte ich die Instanzen 1 und 2 (die zwei Globalen), während mein beabsichtigtes Ergebnis wäre, nur die Instanz zu bekommen 1 (der globale, nicht gelöschte).
Ich war mir nicht sicher, ob jemand in eine ähnliche Situation geraten war und zu einem Ergebnis gekommen war. Entweder ein Weg, um es in meinem aktuellen Denken funktionieren zu lassen oder eine Überarbeitung, die die Funktionalität bietet, nach der ich suche, wäre sehr willkommen. Ich weiß, dass dieser Beitrag ein wenig langatmig war. Wenn weitere Erklärungen benötigt werden, würde ich es gerne zur Verfügung stellen.
Edit:
ich, die Lösung gepostet habe ich unten auf dieses spezifische Problem verwendet. Es basiert auf dem Link zu Simons benutzerdefiniertem QuerySetManager.
, die den Trick getan zu haben scheint. Ich hätte wissen müssen, dass ich mich mehr auf den Abfragesatz und weniger auf den Manager konzentrieren sollte. Ich habe meine mögliche Lösung als Antwort veröffentlicht, obwohl ich Ihre als die beste ausgewählt habe. – Adam