Django: Databázový model

Databáze je základem každého většího webu. Django umožňuje vytvářet databázové modely a pracovat s jejich daty pomocí ORM přístupu. Abychom si to mohli vyzkoušet, představíme si větší aplikaci, kterou budeme postupně budovat.
Seriál: Hrajeme si s Djangem (16 dílů)
- Django: Úvod a instalace 14. 8. 2009
- Django: Nastavení projektu a první pokusy 21. 8. 2009
- Django: Databázový model 28. 8. 2009
- Django: Databázový model podruhé 4. 9. 2009
- Django: Administrace 11. 9. 2009
- Django: Prezentace dat 18. 9. 2009
- Django: Prezentace dat podruhé 25. 9. 2009
- Django: Zpracovávání formulářů 2. 10. 2009
- Django: Autentizace a autorizace 9. 10. 2009
- Django: Nahrávání souborů 16. 10. 2009
- Django: Zabudované aplikace 23. 10. 2009
- Django: Rozšiřování možností Djanga 30. 10. 2009
- Django: Internacionalizace 6. 11. 2009
- Django: Nasazování projektu 13. 11. 2009
- Django: Kešování a škálování 20. 11. 2009
- Django: Závěr 27. 11. 2009
Nálepky:
Pokud chceme manipulovat s daty, což znamená je vytvářet, načítat, upravovat a mazat (anglicky create, read, update and delete, často zkracováno jako CRUD), je potřeba použít nějaké úložiště dat. Relační databáze je příkladem takového úložiště a Django je uzpůsobeno pro její využití, stačí ho jen správně nastavit.
Propojení s databází
Opět se nejprve ponoříme do editování souboru settings.py
, který obsahuje několik konstant, začínajících prefixem DATABASE_
. Ty nastavují propojení Djanga s danou databází. Jak jste se již mohli dočíst v úvodním seznámení, Django podporuje více databázových serverů a my si vybrali databázi SQLite (verze 3), protože je velice jednoduchá na nastavení — stačí změnit pouhé dvě konstanty:
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = '/home/dqd/hrajeme_si/sqlite.db'
Konstanta DATABASE_ENGINE
určuje databázový systém, který hodláme v projektu používat. Dále máme na výběr: 'postgresql_psycopg2'
, 'postgresql'
, 'mysql'
a 'oracle'
. Databáze PostgreSQL má dvě možnosti, přičemž 'postgresql_psycopg2'
je novější verze rozhraní. Druhá konstanta, DATABASE_NAME
, je absolutní cesta k souboru databáze. Nic nezkazíme, když bude soubor s databází uložen v adresáři projektu, ať je to všechno na jednom místě.
Jestliže hodláte pracovat s jiným databázovým systémem než s SQLite, konstanta DATABASE_NAME
nenastavuje umístění, ale název databáze. Měli bychom pak vyplnit další konstanty, DATABASE_USER
a DATABASE_PASSWORD
, jež nastavují jméno a heslo databázového uživatele. Máme také možnost upravit nepovinné konstanty DATABASE_HOST
a DATABASE_PORT
, pomocí kterých můžeme specifikovat doménu a port v případě, že se databázový server nenachází na standardním umístění.
Po uložení konfiguračního souboru provedeme synchronizaci databáze. Tím se vytvoří základní tabulky a budeme mít možnost přidat uživatele s administrátorským oprávněním. Toho později využijeme při přihlašování do administračního rozhraní projektu, takže si přístupové údaje rozhodně zapamatujte. První synchronizace databáze vypadá nějak takto:
$ python manage.py syncdb
Creating table auth_permission
Creating table auth_group
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'dqd'):
E-mail address: id@dqd.cz
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
Pokud synchronizace proběhla úspěšně, můžeme si zkusit spustit příkazový řádek databáze (pravděpodobně bude ale nejprve potřeba nainstalovat balíček sqlite3
):
$ python manage.py dbshell
SQLite version 3.5.9
Enter ".help" for instructions
sqlite> .tables
auth_group auth_user_groups
auth_group_permissions auth_user_user_permissions
auth_message django_content_type
auth_permission django_session
auth_user django_site
sqlite> .quit
Pomocí tohoto příkazového řádku můžeme ručně ovládat databázi, což se někdy může hodit. Každý databázový systém má ovšem trochu odlišnou syntaxi příkazů, takže pozor na to.
Aplikace videopůjčovna
Ponecháme na chvíli Django stranou, protože si teď zkusíme představit aplikaci, na které si budeme vysvětlovat databázový model. Dejme tomu, že dostanete zakázku na vytvoření webu pro síť videopůjčoven. V takové videopůjčovně nepůjčují videorekordéry, ale DVD a Blu-ray disky a také se tam dají nalézt nějaké VHS kazety.
Protože už videopůjčovny nevynáší tolik a je krize, zadavatel se rozhodl šetřit a chce aplikaci co nejjednodušší. Bude mu stačit přehled všech poboček, katalog filmů, informace o půjčování a několik funkcí navíc pro registrované uživatele. Celé to má být ovladatelné přes administraci. Vytvořit něco takového by mělo být v Djangu bez problémů, takže se do toho můžeme rovnou pustit.
Modelujeme
Abychom mohli tvořit nezávisle od předchozích pokusů, založíme si opět novou aplikaci. Můžeme ji nazvat třeba video_store, tedy anglicky videopůjčovna. Aplikaci vytvoříme příkazem python manage.py startapp video_store
a po vytvoření bychom ji měli začlenit mezi aplikace využívající databázi, které jsou zapsány v konstantě INSTALLED_APPS
. Když to uděláme, Django při příští synchronizaci databáze bude hledat modely i v naší nové aplikaci. Konstantu najdeme na konci souboru settings.py
a i s nově přidanou aplikací by měla vypadat nějak takto:
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'hrajeme_si.video_store',
)
INSTALLED_APPS
je potřeba aktualizovat pokaždé, když přidáme novou aplikaci, která má spolupracovat s databázi.Vytvoření prvního modelu
V nově vytvořeném adresáři video_store
si otevřeme soubor models.py
. Do tohoto souboru se zadávají definice modelů, které nám určují schéma databáze. Zjednodušeně řečeno, tabulka je třída a sloupec v tabulce je atribut dané třídy. Všechny modely se odvozují od třídy Model
z modulu django.db.models
. Definice prvního modelu, který má znázorňovat provozovnu videopůjčovny, vypadá takhle:
from django.db import models class Store(models.Model): store = models.CharField('Provozovna', max_length=100) address = models.CharField('Adresa', max_length=100) city = models.CharField('Obec', max_length=100) postal_code = models.CharField('PSČ', max_length=10) email = models.EmailField('E-mail', blank=True) description = models.TextField('Popis', blank=True) def __unicode__(self): return self.store class Meta: verbose_name = 'provozovna' verbose_name_plural = 'provozovny'
settings.py
), takže budou z důvodů čitelnosti vypsány pouhé úryvky kódu.Třída Store
obsahuje několik atributů. První čtyři jsou pole typu CharField
, což odpovídá databázovému typu VARCHAR
, tedy krátkému řetězci. Tento typ potřebuje mít stanovenou maximální délku pomocí parametru max_length
. Atribut email
je typu EmailField
a používá se pro ukládání e-mailových adres. Parametr blank
nastavuje, zda může být obsah dané položky prázdný a má výchozí hodnotu False
(tzn. je potřeba něco zadat). Poslední atribut je typu TextField
, který je v databázi uložen jako TEXT
— tento typ se používá pro ukládání delších textů. Parametr, který stojí u všech položek na prvním místě (lze ho také zadávat jako verbose_name
), slouží k pojmenování atributu a není povinný. Kdybychom ho nezadali, odvodil by se z názvu atributu. Přehled všech typů atributů je opět popsán v oficiální dokumentaci.
Takže každá pobočka bude mít přiřazený nějaký název, adresu a nepovinně e-mailovou adresu a popis. Metoda __unicode__
je unikódová verze metody __str__
, která je v Pythonu používána pro textové znázornění objektu, například při ladícím výpisu. V naší definici se zobrazí název provozovny, což by mělo objekt dostatečně identifikovat. Třída také obsahuje podtřídu Meta
, pomocí které se dají nastavit dodatečné vlastnosti modelu. V našem případě přenastavujeme vlastnosti verbose_name
a verbose_name_plural
. Ty určují název modelu v jednotném a množném čísle. To má pozdější využití v administraci.
Od modelů k databázi
Když máme správně nastavenou databázi a definovali jsme si model, můžeme si nechat vytvořit příslušnou tabulku. Název tabulky se automaticky odvodí z názvu aplikace a modelu, případně ho máme možnost nastavit přes vlastnost modelu db_table
. Každopádně si nejprve ověříme, jestli naše definice modelu neobsahuje nějaké chyby:
$ python manage.py validate
0 errors found
Evidentně je všechno v pořádku a pro zajímavost si můžeme nechat vypsat SQL kód pro vytvoření tabulky:
$ python manage.py sql video_store
BEGIN;
CREATE TABLE "video_store_store" (
"id" integer NOT NULL PRIMARY KEY,
"store" varchar(100) NOT NULL,
"address" varchar(100) NOT NULL,
"city" varchar(100) NOT NULL,
"postal_code" varchar(10) NOT NULL,
"email" varchar(75) NOT NULL,
"description" text NOT NULL
);
COMMIT;
Všimněte si hlavně primárního klíče id
, který se přidává automaticky ke všem tabulkám z důvodů jednoznačné identifikace našich záznamů. A teď si konečně synchronizujeme projekt s databází:
$ python manage.py syncdb
Creating table video_store_store
Vytvořila se nám nová tabulka, do které se budou ukládat data o pobočkách. Protože se k databázi přistupuje pomocí objektů, můžeme si jednoduše spustit interpret Pythonu a ukázat si manipulaci s daty:
$ python manage.py shell
Python 2.5.2 (r252:60911, Jan 4 2009, 21:59:32)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
>>>
) označuje interpret Pythonu. Pokaždé když bude někde uvedený, musíte mít interpret spuštěný příkazem python manage.py shell
a příklady si zkoušet tam. Tento příkaz rovnou načte i nastavení projektu, takže můžeme ihned využívat přístup k databázi.Vkládání záznamů do tabulky
Začneme importem našeho modelu a založením několika objektů poboček:
>>> from hrajeme_si.video_store.models import Store
>>> s1 = Store()
>>> s1.store = 'Videostore Praha'
>>> s1.address = 'Jana Nováka 42'
>>> s1.city = 'Praha 1'
>>> s1.postal_code = '110 00'
>>> s1.email = 'video-store-praha@example.cz'
>>> s1.description = 'Otevřeno denně od 8 do 20 hodin.'
>>> s2 = Store(store='Videostore Praha 2', address='Nepojmenovaná 8', city='Praha 2', postal_code='120 00')
>>> s3 = Store(store='Videostore Brno', address='Náměstí Svobody 1', city='Brno', postal_code='602 00')
Vytvořili jsme si tři instance modelu Store
. V prvním případě je použit prázdný konstruktor a data jsou doplněna později, v dalších dvou data předáváme přímo přes konstruktor. Oba způsoby jsou možné, druhý je preferovaný. Po vytvoření objektů můžeme jejich atributy libovolně měnit a až jsme s výsledkem spokojeni, zavoláme metodu save
, která data uloží do tabulky:
>>> s1.save()
>>> s2.save()
>>> s3.save()
Záznamům se přiřadí automaticky hodnota id
podle pořadí, v jakém byly uloženy. Obsah tabulky poté vypadá takto:
id | store | address | city | postal_code | description | |
---|---|---|---|---|---|---|
1 | Videostore Praha 1 | Jana Nováka 42 | Praha 1 | 110 00 | video-store-praha@example.cz | Otevřeno denně od 8 do 20 hodin. |
2 | Videostore Praha 2 | Nepojmenovaná 8 | Praha 2 | 120 00 | ||
3 | Videostore Brno | Náměstí Svobody 1 | Brno | 602 00 |
Související odkazy
- Modely a tutoriál na Djangoproject.com
- Tutoriál na Djangoproject.cz
- Pátá kapitola v The Definitive Guide to Django
- Ukázkový příklad ke stažení.
Ve čtvrtém díle budeme pokračovat v hraní si s databázovými modely.
Omlouvam se za nulovej prinos komentare, ale proste „id@dqd.cz“ me rozesmalo.
Může tu někdo naznačit jak se instaluje Sqlite3? docela jsem se na tom zaseknul. Jinak zkoušel jsem se připojit k mysql databázi a to mi zatím taky nefunguje. Má někdo nějaké rady? Jinak pěkný článek;-)
Předpokládám, že máte Windows. Tam stačí stáhnout binárku SQLite, rozbalit ji, soubor přemístit do správného adresáře a do příkazové řádky (tj. Start → Spustit →
cmd
) se do toho adresáře přepnout a napsat příkazsqlite3 mojedatabaze.db
. Pokud byste s tím měl potíže, existují různá GUI s instalátorem, jako třeba Sqliteman.