Modeller i Django

Slutförd

Modeller är kärnan i alla ORM. En modell är en representation av vissa data som ditt program kommer att arbeta med. Detta kan vara en person, en produkt, en kategori eller någon annan form av data som ditt program behöver.

Skapa en modell

I Django är en modell alla klasser som ärver en samling funktioner från django.models.Model. Samlingen innehåller metoder som gör att du kan köra frågor mot databasen, skapa nya poster och spara uppdateringar. Du kan också definiera fält, ange metadata och upprätta relationer mellan modeller.

Om du vill skapa två modeller Product och Categorylägger du till två klasser:

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

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

Lägg till metoder

Innan vi diskuterar hur du konfigurerar data för din modell är det viktigt att markera det faktum att en modell är en Python-klass. Därför kan du både lägga till metoder och åsidosätta de som tillhandahåller, eller de som Django.models.Model är inbyggda i alla Python-objekt.

En metod som särskilt ska markeras är __str__. Du använder den här metoden för att visa ett objekt om inga fält har angetts. Om Product har ett name fält (som vi ser på bara ett ögonblick) kan du returnera det som standardsträngrepresentation för Product genom att __str__åsidosätta .

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

Lägg till fält

Fält definierar datastrukturen för en modell. Fält kan innehålla namnet på ett objekt, ett skapandedatum, ett pris eller andra data som modellen behöver lagra.

Olika datadelar har olika datatyper, valideringsregler och andra former av metadata. Django ORM innehåller en omfattande uppsättning alternativ för att konfigurera fälten i dina modeller enligt dina specifikationer. ORM är utökningsbar, så du kan skapa dina egna regler efter behov.

Definiera fälttypen

Kärnan i metadata för alla fält är den typ av data som ska lagras, till exempel en sträng eller ett tal. Fälttyper mappar både till en databastyp och en HTML-formulärkontrolltyp (till exempel en textruta eller en kryssruta). Django innehåller flera fälttyper, bland annat:

  • CharField: En enda textrad.
  • TextField: Flera textrader.
  • BooleanField: Ett booleskt true/false-alternativ.
  • DateField: Ett datum.
  • TimeField: En tid.
  • DateTimeField: Datum och tid.
  • URLField: En URL.
  • IntegerField: Ett heltal.
  • DecimalField: Ett decimaltal med fast precision.

Om du vill lägga till fält i våra Product klasser och Category kan vi ha följande kod:

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()

Fältalternativ

Du kan använda fältalternativ för att lägga till metadata för att tillåta null- eller tomma värden, eller markera ett fält som unikt. Du kan också ange valideringsalternativ och ange anpassade meddelanden för valideringsfel.

Precis som med fälttyper mappas fältalternativen till lämpliga inställningar i databasen. Reglerna tillämpas i alla former som Django genererar åt dig.

Fältalternativ skickas till funktionen för själva fältet. Olika fält kan ha stöd för olika alternativ. Några av de vanligaste är:

  • null
    • Booleskt alternativ för att tillåta null-värden.
    • Standard är False.
  • blank
    • Booleskt alternativ för att tillåta tomma värden.
    • Standard är False.
  • default
    • Tillåter konfiguration av ett standardvärde om ett värde för fältet inte anges.
    • Om du vill ange standardvärdet till en databas nullanger du default till None.
  • unique
    • Det här fältet måste innehålla ett unikt värde.
    • Standard är False.
  • min_length och max_length
    • Används med strängtyper för att identifiera minsta och högsta stränglängd.
    • Standard är None.
  • min_value och max_value
    • Används med taltyper för att identifiera lägsta och högsta värden.
  • auto_now och auto_now_add.
    • Används med datum-/tidstyper för att ange om den aktuella tiden ska användas.
    • auto_now anger alltid fältet till aktuell tid vid sparande, vilket är användbart för last_update fält.
    • auto_now_add anger fältet till den aktuella tiden när det skapas, vilket är användbart för creation_date fält.

Kommentar

Värdena null och blank kan verka liknande, men de betyder olika saker i databastermer. null är bristen på ett värde, medan blank är specifikt ett tomt värde.

Om du vill lägga till alternativ i våra modeller kan koden se ut så här:

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)

Nycklar och relationer

En standardpraxis i relationsdatabaser är att varje rad i en tabell har en primärnyckel, vanligtvis ett automatiskt inkrementellt heltal. Djangos ORM lägger automatiskt till den här nyckeln i varje modell som du skapar genom att lägga till ett fält med namnet id.

Om du vill åsidosätta det här beteendet kan du ange det fält som du vill ska vara din primära nyckel. Du bör dock förlita dig på Djangos id fält i de flesta situationer.

Relationsdatabaser har också relationer mellan tabeller. En produkt har en kategori, en anställd har en chef och en bil har en tillverkare. Djangos ORM stöder alla relationer som du kanske vill skapa mellan dina modeller.

Den vanligaste relationen är "en-till-många", tekniskt sett känd som en sekundär nyckelrelation. I en sekundärnyckelrelation delar flera objekt ett enda attribut. Flera produkter grupperas till exempel i en enda kategori. Om du vill modellera den här relationen använder du fältet ForeignKey .

Om du vill skapa relationen lägger du till fältet i ForeignKey det underordnade objektet. Om dina produkter är grupperade i kategorier lägger du till category egenskapen i Product klassen och anger att typen är ForeignKey.

Django lägger automatiskt till en egenskap till den överordnade egenskapen för att ge åtkomst till alla underordnade objekt med namnet <child>_set, där <child> är namnet på det underordnade objektet. I vårt exempel Category har product_set automatiskt lagts till för att ge åtkomst till alla produkter i kategorin.

ForeignKey har en obligatorisk parameter, on_delete. Den här parametern talar om för Django vad du ska göra om den överordnade filen tas bort. Om vi tar bort en kategori, vad ska hända med produkterna i den kategorin?

De två vanligaste alternativen är:

  • CASCADE, som tar bort alla produkter om en kategori tas bort i vårt exempel.
  • PROTECT, vilket returnerar ett fel om vi försöker ta bort en kategori som innehåller produkter.

Kommentar

I de flesta fall vill du använda PROTECT.

Om du vill uppdatera vår modell för att skapa relationen kan vi använda följande kod:

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