RkBlog

Hardware, programming and astronomy tutorials and reviews.

Modele

Definiowanie struktur i relacji tabel w bazie danych

Model w Django służy do definiowania struktury i relacji tabel w bazie danych. 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.

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

Dodatkowe argumenty pól

Wszystkie pola przyjmują zestaw dodatkowych opcjonalnych argumentów:

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

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()
Również w tej zależności można ustawić zależny model na "self" czyli zależność od siebie samego.

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:
        # ...
W klasie Meta możemy określić kilka parametrów:

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

14 July 2008;

Comment article