2009-05-20 6 views
5

Ich versuche, ein Viele-zu-eins-Feld in der Klasse zu definieren, die das "Viele" ist. Zum Beispiel, eine Situation vorstellen, in dem ein Benutzer nur ein Mitglied einer Gruppe kann sein kann, aber eine Gruppe viele Benutzer:ManyToOneField in Django

class User(models.Model): 
    name = models.CharField() 

class Group(models.Model): 
    name = models.CharField() 
    # This is what I want to do -> users = models.ManyToOneField(User) 

Django docs wird zeigen, ein Gruppenfeld in dem Benutzermodell als ForeignKey zu definieren, aber Ich muss die Beziehung im Gruppenmodell definieren. Soweit ich weiß, gibt es kein ManyToOneField und ich möchte lieber kein ManyToManyField verwenden.

+0

Warum können Sie ForeignKey nicht verwenden? –

+2

Ich arbeite an einem bestehenden Projekt und möchte keine Änderungen an den Basismodellen vornehmen, die das Hauptprojekt weiterhin aktualisiert. – vacanti

Antwort

8

Ein ManyToOne Feld, wie Sie erraten haben, heißt ForeignKey in Django. Sie haben es auf Ihre User Klasse zu definieren, für die Logik richtig funktioniert, aber Django wird ein Reverse-Eigenschaft auf dem Groups Modell zur Verfügung stellen automatisch:

class Group(models.Model): 
    name = models.CharField(max_length=64) 

class User(models.Model): 
    name = models.CharField(max_length=64) 
    group = models.ForeignKey(Group) 

g = Group.objects.get(id=1) 
print g.user_set.all() # prints list of all users in the group 

Denken Sie daran, dass Django Modelle auf einer relationalen Datenbank sitzen. .. Es gibt keine Möglichkeit, ein einzelnes FK-Feld in einer Tabelle zu definieren, die auf mehr als einen Fremdschlüssel verweist (ohne M2M). Daher wird die ManyToOne-Beziehung für das Groups-Objekt nicht dem zugrunde liegenden Datenspeicher zugeordnet. Wenn Sie Raw-SQL schreiben würden, würden Sie diese Beziehung in jedem Fall mit einem Fremdschlüssel aus der Benutzertabelle in die Gruppentabelle modellieren, wenn es Ihnen hilft, so zu denken. Die Syntax und Logik der Verwendung einer ManyToOne -Eigenschaft, die für eine Gruppeninstanz definiert ist, wenn ein solches Konzept vorhanden wäre, wäre viel weniger einfach als die ForeignKey, die für Benutzer definiert ist.

+1

Danke für die Erklärung, warum es nicht möglich war, das zu tun, was ich suchte. Ich werde nur ein viel zu viele Feld verwenden. – vacanti

1

Angenommen, das Benutzerkonstrukt ist das integrierte Authentifizierungssystem ... Ich würde empfehlen, ein Profilmodell irgendeiner Art zu erstellen und stattdessen das OneToMany-Feld anzuhängen. Sie können dann hook the Profile model to the user model.

1

Sie sollten wahrscheinlich in Reverse-Lookups bei einfach mithilfe der integrierten Suche werden:

group = Group.objects.get(id=1) 
users_in_group = group.user_set.all() 

Reverse-Lookup-Sets sind für jegliche Fremdschlüssel oder many-to-many-Beziehungen zu dem Modell in Frage automatisch erstellt.

Wenn Sie diese mit einem freundlicheren Namen beziehen möchten, oder eine zusätzliche Filterung bieten vor der Rückkehr, können Sie immer den Anruf in einem Verfahren wickeln:

class Group(models.Model): 
    name = models.CharField(max_length=64) 

    def users(self): 
     return self.user_set.all() 

Entweder können aus den Vorlagen aufgerufen werden:

{{ group.user_set.all }} 

{{ group.users }} 
+0

Danke! Dies verwende ich mit dem Feld ManyToMany in der Group-Klasse. – vacanti