Modelle in Django

Abgeschlossen

Modelle sind das Herzstück eines jeden ORM. Ein Modell ist eine Darstellung einiger Daten, mit denen Ihre Anwendung arbeitet. Dies kann eine Person, ein Produkt, eine Kategorie oder eine beliebige andere Form von Daten sein, die Ihre Anwendung benötigt.

Erstellen eines Modells

In Django ist ein Modell eine beliebige Klasse, die eine Sammlung von Funktionen von django.models.Model erbt. Die Sammlung enthält Methoden, mit denen Sie die Datenbank abfragen, neue Einträge erstellen und Aktualisierungen speichern können. Sie können auch Felder definieren, Metadaten festlegen und Beziehungen zwischen Modellen einrichten.

Wenn Sie zwei Modelle (Product und Category) erstellen möchten, fügen Sie zwei Klassen hinzu:

from django.db import models
class Product(models.Model):
    # details would go here
    pass

class Category(models.Model):
    # details would go here
    pass

Hinzufügen von Methoden

Bevor wir erläutern, wie Sie die Daten für Ihr Modell konfigurieren, ist es wichtig, die Tatsache hervorzuheben, dass ein Modell eine Python-Klasse ist. Daher können Sie sowohl Methoden hinzufügen als auch die Methoden überschreiben, die Django.models.Model bereitstellt, oder die, die allen Python-Objekten eigen sind.

Eine Methode, die besonders hervorzuheben ist, ist __str__. Sie verwenden diese Methode, um ein Objekt anzuzeigen, wenn keine Felder angegeben sind. Wenn Product ein name-Feld enthält (was wir gleich sehen werden), können Sie es als Standardzeichenfolgendarstellung für Product zurückgeben, indem Sie __str__ überschreiben.

class Product(models.Model):
    name = models.TextField()
    
    def __str__(self):
        return self.name

Hinzufügen von Feldern

Felder definieren die Datenstruktur eines Modells. Felder können den Namen eines Elements, das Erstellungsdatum, einen Preis oder andere Daten enthalten, die vom Modell gespeichert werden müssen.

Verschiedene Daten weisen unterschiedliche Datentypen, Validierungsregeln und andere Formen von Metadaten auf. Der Django-ORM enthält eine umfangreiche Suite von Optionen zum Konfigurieren der Felder ihrer Modelle für ihre Spezifikationen. Der ORM ist erweiterbar, sodass Sie bei Bedarf eigene Regeln erstellen können.

Definieren des Feldtyps

Das Kernstück der Metadaten für alle Felder ist der Datentyp, der gespeichert wird, z. B. eine Zeichenfolge oder eine Zahl. Feldtypen werden sowohl einem Datenbanktyp als auch einem HTML-Formularsteuertyp (z. B. einem Textfeld oder einem Kontrollkästchen) zugeordnet. Django umfasst mehrere Feldtypen, darunter:

  • CharField: Einzelne Textzeile.
  • TextField: Mehrere Textzeilen.
  • BooleanField: Eine boolesche TRUE/FALSE-Option.
  • DateField: Ein Datum.
  • TimeField: Eine Uhrzeit.
  • DateTimeField: Ein Datum und eine Uhrzeit.
  • URLField: Eine URL.
  • IntegerField: Ein Integerwert.
  • DecimalField: Eine Dezimalzahl mit fester Genauigkeit.

Zum Hinzufügen von Feldern zu den Product- und Category-Klassen kann der folgende Code verwendet werden:

from django.db import models
class Product(models.Model):
    name = models.TextField()
    price = models.DecimalField()
    creation_date = models.DateField()

class Category(models.Model):
    name = models.TextField()

Feldoptionen

Sie können Feldoptionen verwenden, um Metadaten hinzuzufügen, um NULL-Werte oder leere Werte zuzulassen, oder ein Feld als eindeutig zu markieren. Sie können auch Validierungsoptionen festlegen und benutzerdefinierte Meldungen für Validierungsfehler bereitstellen.

Wie bei Feldtypen werden Feldoptionen den entsprechenden Einstellungen in der Datenbank zugeordnet. Die Regeln werden in allen Formularen durchgesetzt, die Django in Ihrem Auftrag generiert.

Feldoptionen werden an die Funktion für das Feld selbst übergeben. Verschiedene Felder können unterschiedliche Optionen unterstützen. Einige der gängigsten Optionen sind:

  • null
    • Boolesche Option zum Zulassen von NULL-Werten.
    • Der Standardwert ist False.
  • blank
    • Boolesche Option zum Zulassen von leeren Werten.
    • Der Standardwert ist False.
  • default
    • Ermöglicht die Konfiguration eines Standardwerts, wenn kein Wert für das Feld angegeben wird.
    • Wenn Sie den Standardwert auf eine Datenbank-null festlegen möchten, legen Sie default auf None fest.
  • unique
    • Dieses Feld muss einen eindeutigen Wert enthalten.
    • Der Standardwert ist False.
  • min_length und max_length
    • Wird mit Zeichenfolgentypen verwendet, um die minimale und maximale Zeichenfolgenlänge zu identifizieren.
    • Der Standardwert ist None.
  • min_value und max_value
    • Wird mit Zahlentypen verwendet, um die minimalen und maximalen Werte zu identifizieren.
  • auto_now und auto_now_add.
    • Wird mit Datums-/Uhrzeittypen verwendet, um anzugeben, ob die aktuelle Uhrzeit verwendet werden soll.
    • auto_now legt das Feld immer auf die aktuelle Zeit beim Speichern fest, was für last_update-Felder nützlich ist.
    • auto_now_add legt das Feld auf die aktuelle Zeit bei der Erstellung fest, was für creation_date-Felder nützlich ist.

Hinweis

Die Werte null und blank können ähnlich erscheinen, aber sie bedeuten in Bezug auf die Datenbank unterschiedliche Dinge. null ist das Fehlen eines Werts, während blank speziell ein leerer Wert ist.

Zum Hinzufügen von Optionen zu unseren Modellen könnte der Code wie folgt aussehen:

from django.db import models
class Product(models.Model):
    name = models.TextField(max_length=50, min_length=3, unique=True)
    price = models.DecimalField(min_value=0.99, max_value=1000)
    creation_date = models.DateField(auto_now_add=True)

class Category(models.Model):
    name = models.TextField(max_length=50, min_length=3, unique=True)

Schlüssel und Beziehungen

In relationalen Datenbanken ist es üblich, dass jede Zeile in einer Tabelle einen Primärschlüssel besitzt, normalerweise ein automatisch inkrementierter Integerwert. Der ORM von Django fügt diesen Schlüssel automatisch jedem Modell hinzu, das Sie erstellen, indem ein Feld namens id hinzugefügt wird.

Wenn Sie dieses Verhalten außer Kraft setzen möchten, können Sie das Feld festlegen, das Sie als Primärschlüssel wünschen. In den meisten Fällen sollten Sie jedoch auf das id-Feld von Django zurückgreifen.

Relationale Datenbanken verfügen auch über Beziehungen zwischen Tabellen. Ein Produkt hat eine Kategorie, ein Mitarbeiter hat einen Vorgesetzten, und ein Auto hat einen Hersteller. Der ORM von Django unterstützt alle Beziehungen, die Sie möglicherweise zwischen Ihren Modellen erstellen möchten.

Die gängigste Beziehung ist „1:n“, auch als Fremdschlüsselbeziehung bezeichnet. In einer Fremdschlüsselbeziehung verwenden mehrere Elemente ein einzelnes Attribut gemeinsam. Mehrere Produkte sind z. B. in einer einzelnen Kategorie gruppiert. Um diese Beziehung zu modellieren, verwenden Sie das ForeignKey-Feld.

Um die Beziehung zu erstellen, fügen Sie das ForeignKey-Feld dem untergeordneten Objekt hinzu. Wenn Ihre Produkte in Kategorien gruppiert sind, fügen Sie der Product-Klasse die category-Eigenschaft hinzu und legen den Typ auf ForeignKey fest.

Django fügt dem übergeordneten Element automatisch eine Eigenschaft hinzu, um Zugriff auf alle untergeordneten Elemente namens <child>_set zu ermöglichen, wobei <child> der Name des untergeordneten Objekts ist. In unserem Beispiel wird Category automatisch product_set hinzugefügt, um Zugriff auf alle Produkte in der Kategorie zu ermöglichen.

ForeignKey weist einen obligatorischen Parameter auf: on_delete. Dieser Parameter teilt Django mit, wie vorzugehen ist, wenn das übergeordnete Element gelöscht wird. Das heißt: Wenn wir eine Kategorie löschen, was soll mit den Produkten in dieser Kategorie geschehen?

Die beiden gängigsten Optionen sind:

  • CASCADE, wodurch alle Produkte gelöscht werden, wenn eine Kategorie in unserem Beispiel gelöscht wird.
  • PROTECT, wodurch ein Fehler zurückgegeben wird, wenn versucht wird, eine Kategorie zu löschen, die Produkte enthält.

Hinweis

In der Regel werden Sie PROTECT verwenden wollen.

Um das Modell zum Erstellen der Beziehung zu aktualisieren, können Sie den folgenden Code verwenden:

from django.db import models
class Product(models.Model):
    name = models.TextField()
    price = models.DecimalField()
    creation_date = models.DateField()
    category = models.ForeignKey(
        'Category', #The name of the model
        on_delete=models.PROTECT
    )

class Category(models.Model):
    name = models.TextField()
    # product_set will be automatically created