Heim >Backend-Entwicklung >Python-Tutorial >Django-Dokumentation – in Model
Beziehungsfelder
ForeignKey, ManyToManyField und OneToOneField definieren jeweils viele-zu-eins-, viele-zu-viele- und eins-zu-eins-Beziehungen im Modell.
Zum Beispiel wird ein Buch von einem Verlag veröffentlicht, und ein Verlag kann viele Bücher veröffentlichen. Ein Buch wird von mehreren Autoren geschrieben, und ein Autor kann viele Bücher schreiben.
Klassenautor(models.Model):
name=models.CharField(max_length=20)
Klassenverleger(models.Model):
name=models.CharField(max_length=20 )
Klassenbuch(models.Model):
name=models.CharField(max_length=20)
pub=models.ForeignKey(Publisher)
authors=models.ManyToManyField(Author)
1. Verknüpfung mit einem undefinierten Modell
Wenn Sie eine Verknüpfung mit einem undefinierten Modell herstellen möchten, verwenden Sie den Namen des Modells anstelle des Modellobjekts selbst.
Wenn im Beispiel „Publisher“ und „Author“ nach „Book“ definiert sind, müssen sie in der folgenden Form geschrieben werden:
class Book(models.Model):
name=models. CharField(max_length=20 )
pub=models.ForeignKey('Publisher')
authors=models.ManyToManyField('Author')
2.Model assoziiert sich selbst
Modell kann mit Own einer Viele-zu-Eins-Beziehung verknüpft werden
Klasse People(models.Model):
name=models.CharField(max_length=20)
Leader=models.ForeignKey ('self',blank=True, null=True)
Modell kann auch eine Viele-zu-Viele-Beziehung mit sich selbst haben
Klasse Person(models.Model):
friends = models.ManyToManyField("self")
Standardmäßig ist diese Zuordnung symmetrisch. Wenn Person1 ein Freund von Person2 ist, dann ist Person2 auch ein Freund von Person1
p1=Person()
p1. save()
p2=Person()
p2.save()
p3=Person()
p3.save()
p1 .friends.add(p2,p3)
Wenn Sie im obigen Fall die Freunde von p3 finden möchten, benötigen Sie nicht p3.person_set.all(), sondern verwenden Sie einfach p3.friends .all()
Wenn Sie diese symmetrische Beziehung aufheben möchten, setzen Sie symmetrical auf False
class Person2(models.Model):
friends=(models.ManyToManyField("self" ,symmetrical=False)
Auf diese Weise benötigen Sie p3.person_set.all()
Reverse name related_name
Reverse name, Wird verwendet, um vom verwandten Feld zum verwandten Feld zu zeigen. Beachten Sie dies, wenn Sie abstrakte Modelle definieren , müssen Sie den umgekehrten Namen erst dann explizit angeben, da eine spezielle Syntax ordnungsgemäß funktioniert.
Klassenbuch(models.Model):
name=models.CharField(max_length=20) pub=models.ForeignKey(Publisher,related_name='pub')
authors=models .ManyToManyField(Autor, verwandter_Name='Autor')
Auf diese Weise können Sie verwandten_Name verwenden, wenn Sie Herausgeber oder Autor verwenden, um Buch umgekehrt abzufragen: Publisher1.pub.all() oder Autor1.Autor. alle() .
Wenn Sie keine umgekehrte Beziehung festlegen möchten, setzen Sie related_name auf „+“ oder enden Sie mit „+“.
user = models.ForeignKey(User, related_name='+')
Wenn mehrere ManyToManyFields auf dasselbe Modell verweisen, ist dies bei der umgekehrten Abfrage von FOO_set nicht klar Um welches ManyToManyField-Feld handelt es sich? Umgekehrte Beziehungen können verboten werden:
users = models.ManyToManyField(User, related_name='u+')
referents = models.ManyToManyField(User, related_name='ref+')
4. Datenbankdarstellung
Many-to-one: Django verwendet den ForeignKey-Feldnamen + „_id“ als Spaltennamen in der Datenbank. Im obigen Beispiel BOOK In der Datentabelle gibt es eine Spalte „publisher_id“, die dem Modell entspricht.
Sie können den Spaltennamen dieses Felds ändern, indem Sie explizit db_column angeben. Es ist jedoch nicht erforderlich, den Spaltennamen der Datenbank zu ändern, es sei denn, Sie möchten SQL anpassen.
Viele-zu-viele: Django Erstellen Sie eine Zwischentabelle, um die ManyToManyField-Beziehung darzustellen. Standardmäßig ist der Name der Zwischentabelle die Kombination der beiden relationalen Tabellennamen.
Da einige Datenbanken Beschränkungen hinsichtlich der Länge von Tabellennamen haben, ist der Name der Zwischentabelle automatisch auf 64 Zeichen begrenzt und enthält eine eindeutige Hash-Zeichenfolge. Dies
bedeutet, dass Sie möglicherweise Tabellennamen wie book_authors_9cdf4 sehen. Sie können den Zwischentabellennamen manuell mit der Option db_table angeben.
Wenn Sie die Zwischentabelle jedoch manuell angeben möchten, können Sie die Option „through“ verwenden, um das Modell anzugeben und ein anderes Modell zum Verwalten der Viele-zu-Viele-Beziehung zu verwenden. Und dieses Modell Es ist das Modell, das der Zwischentabelle entspricht:
class Person(models.Model):
name = models.CharField(max_length=128)
def __unicode__(self ):
class Group(models.Model):
name = models.CharField(max_length=128)
member = models.ManyToManyField(Person, through='Membership')
def __unicode__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
member = models.ManyToManyField(Person, through='Membership')
def __unicode__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
date_joined = models.DateField()
Invitation_reason = models.CharField(max_length=64)
Auf diese Weise können Sie aufzeichnen, wann eine Person der Gruppe beitritt.
Um die Beziehung zwischen Person und Gruppe herzustellen, können Sie nicht „Hinzufügen“, „Erstellen“ oder „Entfernen“ verwenden, sondern müssen „Mitgliedschaft“ verwenden.
>>> ringo = Person.objects.create(name="Ringo Starr")
>>> )
>>> beatles = Group.objects.create(name="The Beatles")
>>> m1 = Mitgliedschaft(person=ringo, group=beatles,
. .. date_joined=date(1962, 8, 16),
... Invitation_reason= "Benötigte einen neuen Schlagzeuger.")
>>> 🎜>clear() kann weiterhin verwendet werden
5.1 ForeignKey akzeptiert die folgenden optionalen Parameter, die definieren, wie die Beziehung funktioniert.
ForeignKey.limit_choices_to
Es handelt sich um ein Wörterbuch mit Filterbedingungen und entsprechenden Werten, das zum Filtern zugehöriger Objekte im Django-Verwaltungshintergrund verwendet wird. Verwenden Sie beispielsweise Pythons datetime Modul, zugehörige Objekte herausfiltern, die die Filterbedingungen nicht erfüllen:
limit_choices_to = {'pub_date__lte': datetime.date.today}
Nur zugehörige Objekte mit pub_date vor dem aktuellen Datum sind zulässig ausgewählt werden.
Sie können auch Q verwenden Objekte anstelle von Wörterbüchern, was eine komplexere Filterung ermöglicht. Wenn limit_choices_to ein Q-Objekt ist, ist es nicht verfügbar, wenn das Fremdschlüsselfeld in den raw_id_fields von ModelAdmin platziert wird.
ForeignKey.to_field
Gibt an, mit welchem Feld im zugehörigen Objekt die aktuelle Beziehung verknüpft ist. Standardmäßig zeigt to_field auf den Primärschlüssel des zugehörigen Objekts.
ForeignKey.on_delete
Wenn das mit dem ForeignKey eines Modellobjekts verknüpfte Objekt gelöscht wird, wird dieses Objekt standardmäßig auch kaskadiert zusammen gelöscht.
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)
CASCADE: Standardwert, das Modellobjekt wird dem zugeordnet ForeignKey-Objekt gelöschtSET_NULL: Setzt das ForeignKey-Feld des Modellobjekts auf Null. Natürlich muss null auf True gesetzt werden.
SET_DEFAULT: Setzt das ForeignKey-Feld des Modellobjekts auf den Standardwert.
Schützen: Beim Löschen des mit dem ForeignKey verknüpften Objekts
wird ein ProtectedError generiert, sodass das mit dem ForeignKey verknüpfte Objekt nicht gelöscht wird.
SET(): Setzt das ForeignKey-Feld des Modellobjekts auf den an SET() übergebenen Wert.
def get_sentinel_user():
return User.objects.get_or_create(username='deleted')[0]class MyModel(models.Model):user = models .ForeignKey(User, on_delete=models.SET(get_sentinel_user))
DO_NOTHING: Nichts tun.
5.2 ManyToManyField akzeptiert die folgenden optionalen Parameter, die definieren, wie die Beziehung funktioniert.
ManyToManyField.limit_choices_to
hat die gleiche Verwendung wie ForeignKey.limit_choices_to.
limit_choices_to funktioniert nicht für ManyToManyFields, für die eine Zwischentabelle über den Parameter „through“ angegeben wurde.
ManyToManyField.symmetrical
Funktioniert nur, wenn eine rekursive Viele-zu-Viele-Beziehung definiert wird.
ManyToManyField.through
Zwischentabelle manuell angeben
ManyToManyField.db_table
Geben Sie den Namen der Tabelle in der Datenbank an, in der die Many-to-Tabelle gespeichert ist -viele Beziehungsdaten. Wenn diese Option nicht bereitgestellt wird, generiert Django einen neuen Tabellennamen basierend auf den Namen der beiden relationalen Tabellen als Namen der Zwischentabelle.
6.OneToOneField
class OneToOneField(othermodel[, parent_link=False, **options])
wird verwendet, um eine Eins-zu-Eins-Beziehung zu definieren. Im Großen und Ganzen ist es dasselbe wie ein ForeignKey, der „unique=True“ deklariert Sehr ähnlich, der Unterschied besteht darin, dass Sie bei Verwendung der umgekehrten Zuordnung keine Liste von Objekten, sondern ein einzelnes Objekt erhalten.
Dieses Feld ist sehr nützlich, wenn ein Modell von einem anderen Modell erweitert wird, zum Beispiel: Die Vererbung mehrerer Tabellen (Multi-tableinheritance) wird an das untergeordnete Modell übergeben Dies wird erreicht, indem dem Modell eine Eins-zu-eins-Zuordnung hinzugefügt wird, die auf das übergeordnete Modell verweist.
Diesem Feld muss ein Parameter gegeben werden: die zugehörige Modellklasse. Funktioniert genauso wie ForeignKey, einschließlich rekursiver und verzögerter Assoziationen Egal.
Darüber hinaus akzeptiert OneToOneField die Parameter, die ForeignKey akzeptiert, von denen nur einer OnetoOneField ist Proprietär: OneToOneField.parent_link
Wenn es wahr ist und es auf ein untergeordnetes Modell wirkt, das von einem übergeordneten Modell geerbt wurde (dies kann nicht verzögert werden, vererbt das übergeordnete Modell muss wirklich vorhanden sein), dann wird das Feld zu einer Referenz (oder Verknüpfung), die auf die Instanz der übergeordneten Klasse verweist,
, anstatt wie andere OneToOneFields zum Erweitern der übergeordneten Klasse und zum Erben der Eigenschaften der übergeordneten Klasse verwendet zu werden.
aus django.db Modelle, Transaktion, IntegrityError importieren
Klasse Place(models.Model):
name = models.CharField(max_length=50)
adresse = models. CharField(max_length=80)
def __unicode__(self):
return u"%s the place" % self.name
class Restaurant(models.Model):
place = models.OneToOneField(Place, Primary_key=True)
Serves_hot_dogs = Models.BooleanField()
Serves_pizza = Models.BooleanField()
def __unicode__(self):
return u" %s das Restaurant“ % self.place.name
class Waiter(models.Model):
restaurant = models.ForeignKey(Restaurant)
name = models.CharField(max_length=50)
def __unicode__(self):
return u"%s the Kellner at %s" % (self.name, self.restaurant)
Use Reverse When verbunden, was Sie erhalten, ist keine Liste von Objekten, sondern ein einzelnes Objekt:
>>> p1 = Place(name='Demon Dogs', address='944 W. Fullerton')
>>> p1.save()
>>> ()
>>> p1.restaurant
>>> Place.objects.get(restaurant__place__name__startswith="Demon")
>>> Waiter.objects.filter(restaurant__place__name__startswith="Demon")