2012-04-08 2 views
0

Ich versuche, alle Bestellungen für einen Benutzer zu erhalten, in dem der Benutzer entweder Teil der Vertreter oder Manager des Bestellers ist.Wie schreibe ich eine Django Abfrage auf einem verwirrenden Durchlauf, der in M2O rückwärts geht dann weiter zu M2M

Ich werde besser mit etwas Code erklären. Hier ist der relevante Teil meiner models.py

class Vendor(models.Model) : 
    managers  = models.ManyToManyField(User, related_name = 'managers'  , limit_choices_to = { 'userprofile__user_types' : 4 }) 
    representatives = models.ManyToManyField(User, related_name = 'representatives', limit_choices_to = { 'userprofile__user_types' : 5 }, null = True, blank = True) 

class Order(models.Model) : 
    creator = models.ForeignKey(User, related_name = 'creator') 
    approver = models.ForeignKey(User, related_name = 'approver') 
    vendor = models.ForeignKey(Vendor, null = True, blank = True) 

class UserType(models.Model) : 
    name = models.CharField(max_length = 135) 

    # id |  name 
    #----+------------------ 
    # 1 | tenant 
    # 2 | property manager 
    # 3 | property owner 
    # 4 | vendor manager 
    # 5 | vendor 
    # 6 | viewer 
    # 7 | moderator 
    # 8 | administrator 

class UserProfile(models.Model) : 
    user  = models.OneToOneField(User) 
    user_types = models.ManyToManyField(UserType, null = True, blank = True) 

Um alle Aufträge zu erhalten, die ein Benutzer es erstellt wird einfach:

Order.objects.filter(creator = user.pk) 

Der Grund, warum ich konnte nicht herausfinden, wie diese, weil ich zu bekommen konnte nicht herausfinden, wie filter mit einer OR-Klausel (Manager oder Vertreter) oder Prüfung der Existenz in einer M2M-Beziehung (überprüfen, ob Teil der Manager/Vertreter Liste).

Antwort

1

OK, vor allem diese beiden Bits Syntax zu erklären: zu oder Filter verwenden Sie Q Objekte:

from django.db.models import Q 
results = MyModel.objects.filter(Q(name='daniel') | Q(status='fantastic')) 

und Mitgliedschaft in einer ManyToMany zu testen, verwenden Sie nur =

results = MyModel.objects.filter(user__name='daniel') 

was bedeutet "hat einen Benutzer, dessen Name daniel ist" (und nicht, wie Sie vielleicht denken, "hat nur einen Benutzer, dh daniel").

Also, diese zusammen zu setzen, können Sie tun:

Order.objects.filter(Q(vendor__managers=my_user) | 
        Q(vendor__representatives=my_user)) 
+0

Warum Sie gehen 'managers__user' brauchen? Versuchen Sie, von "Vendor.managers" zu "User" zu wechseln? Kann ich einfach bei 'managers' aufhören (zB' vendor__managers = my_user.pk')? – hobbes3

+0

@ hobbes3 ganz richtig, sorry, oben korrigiert. Ich war durch die Aufnahme des UserProfile in Ihren Code verwirrt und nahm an, dass die M2Ms dort und nicht direkt auf den Benutzer zeigten. Entschuldigung. –

+0

Nein, danke! Ich möchte nur sicherstellen, dass ich es bekomme :-). Da 'vendor_manager 'eine Liste von Zahlen in einer M2M SQL-Kreuztabelle ist, dachte ich, ich müsste mit' my_user.pk' nachsehen, aber das muss ich nicht wirklich? – hobbes3

Verwandte Themen