2016-05-03 21 views
2

Zuallererst muss ich zugeben, dass ich ziemlich neu in all diesen Coding-Sachen bin, aber da ich keine richtige Lösung finden konnte, mache ich es selbst und das Lernen von Code ist wahrscheinlich der beste Weg.Django - Wie baut man ein intermediäres m2m-Modell, das passt?/best practice

Wie auch immer, ich versuche eine App zu erstellen, um verschiedene Titelträger, Meisterschaften und solche Sachen zu zeigen. Nachdem ich die Django-Dokumentation gelesen hatte, fand ich heraus, dass ich Zwischenmodelle als einen besseren Weg verwenden muss. Mein alter models.py sieht wie folgt aus:

class Person(models.Model): 
    first_name = models.CharField(max_length=64) 
    last_name = models.CharField(max_length=64) 
    [...] 

class Team(models.Model): 
    name = models.CharField(max_length=64) 
    team_member_one = models.ForeignKey(Person) 
    team_member_two = models.ForeignKey(Person) 

class Championship(models.Model): 
    name = models.CharField(max_length=128) 
    status = models.BooleanField(default=True) 

class Titleholder(models.Model): 
    championship = models.ForeignKey(Championship) 
    date_won = models.DateField(null=True,blank=True) 
    date_lost = models.DateField(null=True,blank=True) 
    titleholder_one = models.ForeignKey(Person,related_name='titleholder_one',null=True,blank=True) 
    titleholder_two = models.ForeignKey(Person,related_name='titleholder_two',null=True,blank=True) 

Meisterschaft kann entweder durch Einzelpersonen oder Teams gewonnen werden, je nachdem, ob es sich um eine Einzel- oder Team-Meisterschaft ist, das ist, warum ich in der Titelverteidiger Klasse Fremdschlüssel hatte. Mit Blick auf die Django documentation scheint dies einfach falsch. Auf der anderen Seite, für mich als Anfänger, scheint das Zwischenmodell im Beispiel einfach nicht zu meinem Modell zu passen.

Lange Rede, kurzer Sinn: Kann mir jemand in die richtige Richtung zeigen, wie man das Modell richtig baut? Hinweis: Das ist nur eine Frage, wie man die Modelle erstellt und im Django-Admin anzeigt, ich spreche nicht einmal über das Erstellen der Templates ab sofort.

Hilfe würde sehr geschätzt werden! Vielen Dank im Voraus Jungs.

+1

Djangos 'ManyToManyField' ist nur syntaktischer Zucker zum automatischen Erstellen und Abfragen einer Zwischentabelle. Wenn Sie die Tabelle explizit erstellen, wie Sie es hier getan haben, brauchen Sie das Feld nicht (obwohl es immer noch hilfreich sein kann). Es gibt jedoch eine Reihe von Problemen mit dem von Ihnen vorgestellten Schema. Keiner von ihnen hat etwas mit Django zu tun, es ist eine Frage der SQL-Datenbankmodellierung. Ich schlage vor, eine allgemeinere Frage zu stellen (* wie kann ich diese Daten modellieren? Hier ist, was ich versucht habe ... *) und es mit [Tag: Datenbank-Design] oder [Tag: Datenmodellierung] versehen. –

Antwort

0

Also werde ich es von Grund auf neu aufnehmen. Sie scheinen E-R Database Modeling etwas neu zu sein. Wenn ich versuchen würde, das zu tun, was Sie tun, würde ich meine Modelle auf die folgende Art und Weise erstellen.

Erstens wäre Team mein "Eck" -Modell gewesen (ich benutze diesen Ausdruck, um Modelle zu meinen, die keine FK-Felder haben), und dann würde das Personenmodell wie folgt ins Spiel kommen.

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

class Person(models.Model): 
    first_name = models.CharField(max_length=64) 
    last_name = models.CharField(max_length=64) 
    team = models.ForeignKey(to=Team, null=True, blank=True, related_name='members') 

Diese effektiv macht die Modelle skalierbar, und selbst wenn Sie werden nie mehr als zwei Personen in einem Team haben, ist dies eine gute Praxis.

Als nächstes kommt das Championship-Modell. Ich würde dieses Modell direkt mit dem Personenmodell als eine Viele-zu-Viele-Beziehung mit einem "Durch" -Modell wie folgt verbinden.

class Championship(models.Model): 
    name = models.CharField(max_length=64) 
    status = models.BooleanField(default=False) # This is not a great name for a field. I think should be more meaningful. 
    winners = models.ManyToManyField(to=Person, related_name='championships', through='Title') 

class Title(models.Model): 
    championship = models.ForeignKey(to=Championship, related_name='titles') 
    winner = models.ForeignKey(to=Person, related_name='titles') 
    date = models.DateField(null=True, blank=True) 

Dies ist nur die Art, wie ich es getan hätte, basierend auf was ich verstanden habe. Ich bin mir sicher, dass ich nicht alles verstanden habe, was Sie zu tun versuchen. Wenn sich mein Verständnis ändert, kann ich diese Modelle an meine Bedürfnisse anpassen.

Ein anderer Ansatz, der verwendet werden kann, besteht darin, ein GenericForeignKey-Feld zu verwenden, um ein Feld zu erstellen, das ein FK entweder für das Teammodell oder das Personenmodell sein kann. Oder eine andere Sache, die geändert werden kann, könnte sein, dass Sie ein weiteres Modell hinzufügen, um die Details jedes Mal zu speichern, wenn eine Meisterschaft stattgefunden hat. Es gibt viele Möglichkeiten, und es gibt keinen richtigen Weg.

Lassen Sie mich wissen, wenn Sie irgendwelche Fragen haben, oder irgendetwas, das ich nicht behandelt habe. Ich werde versuchen, die Antwort je nach Bedarf zu ändern.