Lekce 6 - Databáze filmů v Django - Databáze
V minulé lekci, Databáze filmů v Django - Vytvoření projektu a static files, jsme započali tvorbu nového projektu, kterým je webová databáze filmů.
V následujícím tutoriálu webových aplikací s frameworkem Django v Pythonu pokročíme v tvorbě naší aplikace - Filmové databáze. Zatím máme v aplikaci vytvořenou šablonu a data o filmu jsme jí předali jako seznam. Samozřejmě by bylo hezké mít data uložená v databázi, jak se na správnou webovou aplikaci sluší a patří. A právě na databázi se nyní zaměříme. Vysvětlíme si ORM přístup, vytvoříme modely pro filmy a jejich žánry, databázi zmigrujeme a naučíme se pracovat s Django administrací.
Databáze a Django
Jako databázi budeme používat SQLite, která je v Django již přednastavená a nemusí se na rozdíl od jiných databází instalovat ani konfigurovat. Nutné minimum znalostí a základy práce s ní si vysvětlíme přímo zde v kurzu. Pokud bychom ovšem v budoucnu vytvářeli komplexnější aplikace, je vhodnější použít např. databázi PostgreSQL nebo MySQL. Pro nás by ale teď představovaly zbytečné úsilí navíc.
Objektově relační mapování
S databází budeme pracovat pomocí tzv. ORM - objektově
relačního mapování. Zní to sice velmi odborně, ale ve skutečnosti nám
tento přístup výrazně usnadní práci. My totiž budeme pracovat s objekty a
Django je bude sám na pozadí automaticky převádět na databázové
příkazy. K vytvoření databázových tabulek nám tedy postačí vytvořit
třídy reprezentující databázové entity. Korespondující tabulky budou
později založené automaticky. Jdeme na to Vytvořme si třídy
Film
a Zanr
.
Přejděme do souboru mysite\moviebook\models.py
a upravme jeho
obsah do následující podoby:
from django.db import models class Film(models.Model): nazev = models.CharField(max_length=200) rezie = models.CharField(max_length=180) class Zanr(models.Model): film = models.ForeignKey(Film, on_delete=models.CASCADE) nazev_zanru = models.CharField(max_length=80)
Vidíme, že filmy mají názvy a režii, žánry mají filmy a názvy
žánrů. Kromě definice textových sloupců zde vidíme i definici cizího
klíče, tedy vazby mezi dvěma databázovými tabulkami, v našem případě
vazbu žánru na film. Všimněme si také, že naše třídy dědí z
models.Model
. Díky tomu získají např. metodu
save()
, která jejich instance umožní uložit do databáze. To si
vyzkoušíme za chvíli.
Migrace databáze
Úpravě databáze tak, aby odpovídala definici modelů v naší aplikaci, se říká migrace. Tento proces musíme spustit pokaždé, když provedeme změnu v definici datové struktury a potřebujeme, aby Django na jejím základě databázi upravilo, v našem případě dokonce vytvořilo.
Databázovou migraci nejprve vytvoříme příkazem v terminálu ve složce
mysite/
:
py manage.py makemigrations moviebook
Django nás odmění následujícím výstupem:
Vytvoření migrace: Migrations for 'moviebook': moviebook\migrations\0001_initial.py - Create model Film - Create model Zanr
Poté migraci spustíme:
py manage.py migrate
Výstupem bude:
Spuštění migrace: Operations to perform: Apply all migrations: admin, auth, contenttypes, moviebook, sessions Running migrations: Applying moviebook.0001_initial... OK
Django API
Nyní si ukážeme práci s Django API, tedy jak do databáze vkládat nové řádky jako objekty a jak objekty z databáze také získávat. Ukázky provedeme v interaktivním shellu, který spustíme pomocí:
py manage.py shell
A do něj napíšeme následující kód:
from moviebook.models import Film, Zanr muj_film = Film(nazev="Strazci Galaxie", rezie="James Gunn") # Vytvoříme si nový film muj_film.save() # Uloží film do DB muj_film.zanr_set.create(nazev_zanru="Fantasy/Action") # Vytvoří nový žánr k tomuto filmu nazev_zanru = muj_film.zanr_set.first().nazev_zanru # Získá žánr pro konkrétní instanci filmu
Shell jej provede bez viditelného výstupu. Přesvědčíme se tedy, že vše proběhlo jak mělo. Do shellu vložíme postupně tyto dva příkazy:
muj_film.nazev # Zobrazí název filmu nazev_zanru # Zobrazí název žánru
Ve výstupu vidíme film i žánr:
Zobrazení objektů databáze:: In [2]: muj_film.nazev Out[2]: 'Strazci Galaxie' In [3]: nazev_zanru Out[3]: 'Fantasy/Action'
Rozšíření modelů
Upravme teď naše třídy v modelu tak, aby nám vracely název a jméno režiséra a název žánru:
from django.db import models class Film(models.Model): nazev = models.CharField(max_length=200) rezie = models.CharField(max_length=180) def __str__(self): return "Nazev: {0} | Rezie: {1}".format(self.nazev, self.rezie) class Zanr(models.Model): film = models.ForeignKey(Film, on_delete=models.CASCADE) nazev_zanru = models.CharField(max_length=80) def __str__(self): return "Film: {0} | Nazev_zanru: {1}".format(self.film, self.nazev_zanru)
Pokud jsme stále v interaktivním shellu, tak ho ukončíme příkazem
quit()
a spustíme novou relaci příkazem
py manage.py shell
. Do shellu nyní vložíme:
from moviebook.models import Film, Zanr Film.objects.all() # Uvidíme název filmu i jméno režiséra muj_film = Film.objects.get(nazev="Strazci Galaxie") muj_film.zanr_set.all() # Zobrazí informace o filmu a také název žánru
Výstup v konzoli:
Výpis záznamu v databázi::
<QuerySet [<Zanr: Film: Nazev: Strazci Galaxie | Rezie: James Gunn | Nazev_zanru: Fantasy/Action>]>
Administrace databáze
Konečně se dostáváme k administraci. Vytvoříme si tzv. superuživatele (administračního uživatele) přes kterého databázi budeme moci spravovat. Do konzole zadáme:
py manage.py createsuperuser
Budeme vyzváni k zadání jména, emailu a hesla, zadejme vhodné údaje:
Vytvoření superživatele:
Username (leave blank to use 'tomse'):
Email address:
Password:
Password (again):
Superuser created successfully.
Superživatele máme vytvořeného. Teď je třeba naše modely do
administrace zaregistrovat. To provedeme úpravou souboru
\mysite\moviebook\admin.py
:
from django.contrib import admin from .models import Film, Zanr #Importujeme si modely #Modely registrujeme admin.site.register(Film) admin.site.register(Zanr)
Nyní si spustíme server a zamíříme si to na adresu
http://localhost:8000/admin/
. Přihlašujeme se jako superuživatel
údaji, které jsme si předtím zvolili. Po přihlášení se nám naskytne
následující pohled:

Všímavé do očí uhodí Films
a Zanrs
, to
změníme později. Otevřeme entity Films
a tam uvidíme náš
film s názvem Strazci Galaxie
. Všimněme si, že je nám vypsána
návratová hodnota naší metody __str__()
, kterou jsme si
vytvořili v \mysite\moviebook\models.py
, v případě filmu tedy
jeho název, svislítko a režie:

Pokud si entitu (film
) rozklikneme, můžeme zde editovat jeho
název a jméno režiséra. Pro ukázku si vytvoříme další libovolný film
(Films
-> tlačítko Add Film
vpravo nahoře).
Poté si to namíříme do sekce Zanrs
a zobrazíme si detail o
našem stávajícím žánru. Pokud se pokusíme nastavit žánru film, tak se
nám také zobrazí náš nový film, jak můžeme pozorovat na následujícím
obrázku:

V aplikaci máme nyní chybu, bylo by totiž logické, aby se film vázal na
žánr a ne naopak. Otevřeme si proto náš databázový model u aplikace
moviebook
a relaci změníme, před tímto krokem nejlépe smažme
všechny stávající filmy a žánry. Alespoň si tím procvičíme práci s
databází. Odstranění můžeme provést jednoduše přes administraci.
Přejdeme do souboru \mysite\moviebook\models.py
, který upravíme
do následující podoby:
from django.db import models class Zanr(models.Model): nazev_zanru = models.CharField(max_length=80) def __str__(self): return "Nazev_zanru: {0}".format(self.nazev_zanru) class Film(models.Model): nazev = models.CharField(max_length=200) rezie = models.CharField(max_length=180) zanr = models.ForeignKey(Zanr, on_delete=models.SET_NULL, null=True) def __str__(self): return "Nazev: {0} | Rezie: {1} | Zanr: {2}".format(self.nazev, self.rezie, self.zanr.nazev_zanru)
Dále je potřeba provedené změny modelu "promítnout do databáze", proto použijeme následující, již známé, příkazy pro vytvoření a spuštění migrace:
py manage.py makemigrations moviebook py manage.py migrate
Nyní stačí server znovu spustit a vyzkoušet si, že vše funguje. Jako
první však musíme vytvořit žánr, protože jsme změnili vztah mezi filmy a
žánry (zanr
> film
) a film se musí na nějaký
žánr vázat, aby mohl být vytvořený. Přidání filmu poté vypadá
takto:

Výtečně, vše funguje, jak má. Určitě nás již také nebaví dívat se
na zkomolená slova "Films" a "Zanrs", a proto si trošku upravíme modely
Film
a Zanr
. K tomu použijeme třídu
Meta
, která slouží pro ukládání/nastavení informací navíc,
jako je v tomto případě název množného čísla entity nastavitelný
pomocí "verbose_name_plural". Soubor \mysite\moviebook\models.py
ještě jednou upravíme takto:
from django.db import models class Zanr(models.Model): nazev_zanru = models.CharField(max_length=80, verbose_name="Žánr") def __str__(self): return "Nazev_zanru: {0}".format(self.nazev_zanru) class Meta: verbose_name = "Žánr" verbose_name_plural = "Žánry" class Film(models.Model): nazev = models.CharField(max_length=200, verbose_name="Název Filmu") rezie = models.CharField(max_length=180, verbose_name="Režie") zanr = models.ForeignKey(Zanr, on_delete=models.SET_NULL, null=True, verbose_name="Žánr") def __str__(self): return "Nazev: {0} | Rezie: {1} | Zanr: {2}".format(self.nazev, self.rezie, self.zanr.nazev_zanru) class Meta: verbose_name = "Film" verbose_name_plural = "Filmy"
Namíříme si to rovnou do administrace na
http://localhost:8000/admin/
, kde již můžeme pozorovat krásné
české pojmenování našich modelů.
Údaje pro superuživatele pro databázi v přiloženém projektu jsou následující: Username: karel, Password: heslojeveslo.
V další lekci, Databáze filmů v Django - Generic Views a Formuláře, naprogramujeme práci s databází přes naší aplikace pomocí generic views.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 189x (1.29 MB)
Aplikace je včetně zdrojových kódů v jazyce Python