Modele
14 July 2008
Comments
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"
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)
CREATE TABLE mojaaplikacja_person (
"id" serial NOT NULL PRIMARY KEY,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL
);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.
Pola w modelach
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()
- 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ść.
Dodatkowe argumenty pól
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.
Pierwsza tupla zawiera wartości do zapisania, a druga czytelne dla ludzi opcje wyboru.
YEAR_IN_SCHOOL_CHOICES = ( ('FR', 'Freshman'), ('SO', 'Sophomore'), ('JR', 'Junior'), ('SR', 'Senior'), ('GR', 'Graduate'), ) - 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.
Relacje
MANY-TO-ONE - Wiele do jednego
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()
One-To-One - Jeden do jednego
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)
MANY-TO-MANY - Wiele do wielu
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()
Metadane
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:
# ...
- 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). 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.
ordering = ['-order_date'] ordering = ['-pub_date', 'author']
- 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"
Własne polecenia SQL
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
RkBlog
Comment article