Ich versuche, einen Weg zu finden, um eine benutzerdefinierte QuerySet
und eine benutzerdefinierte Manager
zu implementieren, ohne DRY zu brechen. Dies ist, was habe ich bisher:Benutzerdefinierte QuerySet und Manager ohne DRY zu brechen?
class MyInquiryManager(models.Manager):
def for_user(self, user):
return self.get_query_set().filter(
Q(assigned_to_user=user) |
Q(assigned_to_group__in=user.groups.all())
)
class Inquiry(models.Model):
ts = models.DateTimeField(auto_now_add=True)
status = models.ForeignKey(InquiryStatus)
assigned_to_user = models.ForeignKey(User, blank=True, null=True)
assigned_to_group = models.ForeignKey(Group, blank=True, null=True)
objects = MyInquiryManager()
Das funktioniert gut, bis ich so etwas tun:
inquiries = Inquiry.objects.filter(status=some_status)
my_inquiry_count = inquiries.for_user(request.user).count()
Diese prompt bricht alles, weil die QuerySet
nicht die gleichen Methoden wie die Manager
. Ich habe versucht, eine benutzerdefinierte QuerySet
Klasse zu erstellen und es in MyInquiryManager
zu implementieren, aber am Ende repliziere ich alle meine Methodendefinitionen.
Ich fand auch this snippet, das funktioniert, aber ich brauche, um for_user
in dem zusätzlichen Argumente übergeben, so nach unten bricht, weil es neu zu definieren get_query_set
stark auf beruht.
Gibt es eine Möglichkeit, dies zu tun, ohne alle meine Methoden in den Unterklassen QuerySet
und Manager
neu zu definieren?
Warnung: Die ausgewählte Antwort von T.Stone führt zu einer schwerwiegenden Leistungseinbuße (von Millisekunden-Antwortzeiten zu Antworten mit mehreren Sekunden), wenn die Methoden .defer oder only verwendet werden. Zum Beispiel, in Django 1.3 eine Abfrage wie zum Beispiel: MyModel.objects.only ('some_field'). Get (id = 1) => gibt in 3.7ms zurück, aber, fügen Sie den CustomManager wie oben beschrieben hinzu, und ich bekomme: MyModel.objects .only ('some_field'). get (id = 1) => kehrt in ~ 357ms zurück –
Hat jemand anderes dies reproduziert? Was ist mit Django 1.4? – fletom
Okay. Aber warum und wie passiert das? Sind die Abfragen anders oder haben Sie diese Operation profiliert, ohne tatsächlich auf die Datenbank zu treffen? –