Model w Django służy do definiowania struktury i relacji tabel w bazie danych.
- Każdy model jest klasą Pythona dziedziczącą django.db.models.Model
- Każda właściwość klasy-modelu określa pole w bazie danych
- Dane nie związane z polami w bazie danych umieszczane są w wewnętrznej klasie "Meta"
W django nie posługujemy się "na co dzień" językiem SQL. Operacje na bazach danych są przeprowadzane przez ORM Django.
Modele dla danej aplikacji znajdują się w pliku
nazwa_aplikacji/models.py. Oto prosty przykład:
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
Definiujemy klasę Person posiadającą dwa pola - first_name i last_name. Czyli mamy klasę "zarządzającą" osobami zbierając ich imię i nazwisko. Dla powyższego modelu Django wygenerowałoby odpowiednią tabelę w bazie danych, a dokładniej (w przypadku postgresa):
CREATE TABLE mojaaplikacja_person (
"id" serial NOT NULL PRIMARY KEY,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL
);
Django automatycznie dodaje pole id (co można obejść) oraz automatycznie stosuje nazewnictwo tabel w postaci "mojaaplikacja_model" co też można obejść (czytaj dalej).
Po stworzeniu modelu by wygenerować tabele (i resztę danych typu uprawnienia) należy wykonać polecenie python manage.py syncdb w katalogu projektu.
Django nie posiada jeszcze opcji aktualizacji już istniejących tabel, co w przypadku zmian w modelach może nam przysporzyć trochę ręcznej pracy.
W powyższym przykładzie modelu pojawiło się pole CharFiled:
models.CharField. Django ma zdefiniowaną listę różnych pól zdolnych przechowywać określone typy danych. Te pola jak już wiemy określają strukturę tabeli w bazie danych, jak również określają pewne zachowania frameworka. Kolejny przykład:
class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ForeignKey(Musician)
name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()
Mamy dwa modele - Muzyk i Album. Każdy album ma swojego autora - muzyka, co jest określane przez
ForeignKey(Musician) - pole ForeignKey oznacza numer id wpisu z innego modelu (w tym przypadku id jakiegoś muzyka - model Musician). A żeby wszystko wyjaśnić - przegląd pól:
- AutoField - pole IntegerField z automatycznie przyrastającymi wartościami. Zazwyczaj nie trzeba tego używać jako że Django domyślnie dodaje pole id tego typu do tabel.
- BooleanField - Pole zawierające wartość Prawda/Fałsz. W panelu admina widoczne jako checkbox.
- CharField - pole tekstowe na nieduże ilości tekstu, wymagany parametr max_length określa maksymalną długość. Dla większych ilości tekstu należy stosować TextField. Panel admina przedstawia to jako input text - jednowierszowe pole.
- CommaSeparatedIntegerField - liczby całkowite oddzielone przecinkami. Parametr max_length wymagany.
- DateField - Pola daty. Panel admina przedstawia to pole jako input text z kalendarzem.
- DateTimeField - Data i czas.
- EmailField - pole CharField do przechowywania adresów email. Sprawdza poprawność dodawanych danych, nie przyjmuje parametru max_length.
- FileField - pole ładowania pliku. Wymaga parametru " upload_to" określającego pełną ścieżkę systemową - katalog, w którym ma być umieszczony plik. Ścieżka może zawierać formatowanie strftime. Dodatkowo należy w konfiguracji projektu określić MEDIA_ROOT - ścieżkę do katalogu z plikami statycznymi (w tym tymi ładowanymi). By ładowanie działało użytkownik, pod którym działa serwer musi mieć prawo zapisu dla podanego katalogu. upload_to określa nam do jakiego podkatalogu przesłać ładowany plik (względem MEDIA_ROOT). W bazie danych zapisana zostanie relatywna ścieżka do pliku względem MEDIA_ROOT. By w szablonie uzyskać pełną ścieżkę zastosuj {{ object.get_NAZWAPOLA_url }}.
- FilePathField - pole z wyborem ograniczonym do nazw plików z określonego katalogu. Posiada trzy dodatkowe argumenty: path (wymagany) - określa ścieżkę do katalogu, z którego pole ma czerpać listę plików, match - wyrażenie regularne używane do filtrowania dostępnych plików. recursive - określa czy zawartość podkatalogów również powinna być uwzględniania, domyślnie False.
FilePathField(path="/home/images", match="foo.*", recursive=True)
- DecimalField, FloatField - pola dla liczb zmiennoprzecinkowych odpowiednio dla Pythonowych obiektów Decimal i Float. Wymaga dwóch dodatkowych argumentów: max_digits - maksymalna ilość cyfr, decimal_places - ilość cyfr po przecinku. Przykład, by zapisywać liczby do 999 z dwoma cyframi po przecinku zastosujemy:
models.DecimalField(..., max_digits=5, decimal_places=2)
- ImageField - pole takie jak FileField z tym że sprawdza czy plik jest grafiką. Posiada dwa opcjonalne argument - height_field i width_field, które jeżeli użyte będą przechowywały bierzące rozmiary grafiki. Wymaga Python Imaging Library.
- IntegerField - Pole na liczby całkowite.
- IPAddressField - Pole na adres IP.
- NullBooleanField - Podobne do BooleanField lecz zezwala również na wartość "NULL". W Panelu Admina widoczne jako lista z opcjami "Tak", "Nie", "Nie wiadomo".
- PhoneNumberField - Pole CharField sprawdzające poprawność podanej wartości jako numeru telefonu w USA - "XXX-XXX-XXXX".
- PositiveIntegerField - Pole na dodatnie liczby całkowite.
- PositiveSmallIntegerField - Jak powyższe z tym że ogranicza wartości zgodnie z ograniczeniami danej bazy danych.
- SlugField - Pole stosowane jako etykieta czegoś (stosowanie na stronach z nowościami itd.) Zawierać może tylko liczby, litery i podkreślenia. Posiada opcjonalny parametr max_length określający długość (domyślnie 50). Zazwyczaj stosuje się to w linkach.
- SmallIntegerField - Tak jak IntegerField lecz z ograniczeniem wartości takim jak dla danej bazy danych.
- TextField - Pole na tekst. Reprezentowane w panelu admina przez textarea.
- TimeField - Pole przechowujące czas.
- URLField - Pole na adres URL. Django automatycznie sprawdza czy URL jest poprawny (tj. strona istnieje i nie zwraca błędu 404). By to wyłączyć należy podać parametr verify_exists=False.
- USStateField - Dwuliterowy skrót stanu USA.
- XMLField - Pole na dane w formacie XML. Wymaga parametru schema_path zawierającego ścieżkę do schematu RelaxNG, względem którego będzie sprawdzana poprawność.
Wszystkie pola przyjmują zestaw dodatkowych opcjonalnych argumentów:
- null - Jeżeli ma wartość True django zapisze puste wartości jako NULL. Domyślnie fałsz.
- blank - Jeżeli ma wartość True django dopuści puste pola. Odnosi się do walidacji formularzy.
- choices - lista lub tupla dwóch tupli zawierająca możliwości do wyboru. W panelu admina input text zostanie zamieniony na select.
YEAR_IN_SCHOOL_CHOICES = (
('FR', 'Freshman'),
('SO', 'Sophomore'),
('JR', 'Junior'),
('SR', 'Senior'),
('GR', 'Graduate'),
) Pierwsza tupla zawiera wartości do zapisania, a druga czytelne dla ludzi opcje wyboru.
- core - Dotyczy obiektów edytowanych przy zależnym innym obiekcie w Panelu Admina (inline edit). Pola z wartością core=True będę uważane za wymagane. Jeżeli wszystkie pola z tą opcją będą puste, obiekt zostanie skasowany.
- db_column - opcjonalna nazwa (niestandardowa) tabeli.
- db_index - Jeżeli True to django-admin.py sqlindexes wygeneruje polecenie CREATE INDEX dla danego pola.
- default - Domyślna wartość pola.
- help_text - Pomocniczy tekst wyświetlany w formularzach Panelu Admin
- primary_key - Jeżeli True dane pole będzie miało atrybut PRIMARY KEY. Jeżeli nie podane to django automatycznie wygeneruje pole id z tym atrybutem.
- unique - Jeżeli True pole będzie miało atrybut UNIQUE i będzie musiało zawierać unikalne (niepowtarzalne) wartości.
Z tej zależności już skorzystaliśmy w przykładzie:
class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ForeignKey(Musician)
name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()
Gdzie wpis w jednej tabeli zależy (ma przypisany) od wpisu z innej tabeli. Zależność MANY-TO-ONE określana jest przez pole
ForeignKey(MODEL). Zamiast nazwy modelu możemy podać "self" by uzyskać zależność modelu od siebie samego.
Prosta relacja podobna do MANY-TO-ONE, z tym że jednemu rekordowi z tabeli A odpowiada jeden rekord z tabeli B. Obrazuje to poniższy przykład gdzie użytkownik może mieć tylko jeden profil.
class UserProfile(models.Model):
user = models.OneToOneField(User, primary_key=True)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
Ta zależność nieco różni się od poprzedniej. Korzystając z wcześniejszego przykładu Album mógłby mieć wielu autorów/muzyków (a muzycy mogą mieć wiele albumów).
class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ManyToManyField(Musician)
name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()
Również w tej zależności można ustawić zależny model na "self" czyli zależność od siebie samego.
Metadane służą do opisu i konfiguracji modelu. Umieszczamy je w klasie Meta:
class Foo(models.Model):
bar = models.CharField(max_length=30)
class Meta:
# ...
W klasie Meta możemy określić kilka parametrów:
- db_table - niestandardowa nazwa tabeli.
- get_latest_by - określa nazwę pola typu DateField lub DateTimeField według wartości której sortować i określać "ostatnie wpisy" dla metody latest()
- order_with_respect_to - sortowanie względem zależnego pola:
class Answer(models.Model):
question = models.ForeignKey(Question)
# ...
class Meta:
order_with_respect_to = 'question'
- ordering - oznacza domyślne sortowanie (pole i sposób).
ordering = ['-order_date']
ordering = ['-pub_date', 'author']
Pierwszy przykład posortuje malejąco (znak -) a drugi posortuje malejąco względem pola pub_date a następnie rosnąco względem pola author. Znak ? posortuje elementy losowo.
- permissions - określa dodatkowe (oprócz add, delete, change) uprawnienia dla obiektów danego modelu:
permissions = (("czy_moze_costam", "Czy może cośtam"),)
Jest to tupla złożona z podwójnych tupli gdzie pierwszy element to nazwa uprawnienia dla systemu a druga to nazwa uprawnienia czytelna dla człowieka.
- unique_together - określa pola, które zestawione razem muszą być unikalne. Dotyczy to bazy danych i panelu admina.
unique_together = (("driver", "restaurant"),)
Jest to lista złożona z list zawierających nazwy pól.
- verbose_name - nazwa obiektu czytelna dla człowieka.
- verbose_name_plural - nazwa obiektu czytelna dla człowieka w liczbie mnogiej. Jeżeli nie podana django użyje verbose_name + "s"
Django umożliwia wykonywanie własnych poleceń SQL poprzez API zgodne z Pythonowym DB-API (
dokumentacja DB-API):
def my_custom_sql(self):
from django.db import connection
cursor = connection.cursor()
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
return row
- Dodane: 14.07.2008 przez riklaunim