6. diel - Databázy filmov v Django - Databáza
V minulej lekcii, Databázy filmov v Django - Vytvorenie projektu a static files , sme začali tvorbu nového projektu, ktorým je webová databáza filmov. Zatiaľ máme vytvorenú šablónu a dáta o filme sme jej odovzdali ako list. Samozrejme by bolo pekné mať dáta uložené v databáze a nie v liste, ako sa na správnu webovú aplikáciu sluší a patrí. Práve databáze je venovaný celý dnešný tutoriál.
Databázy
Ako databáze budeme používať SQLite, ktorá je v Django už prednastavené a nemusí sa na rozdiel od iných databáz inštalovať ani konfigurovať. Ak ste o nej ešte nepočuli, nevadí, nutné minimum bude vysvetlené priamo tu v kurze. Detailné prácu s databáze sa prípadne naučíte po navštívení uvedeného odkazu. Ak by ste v budúcnosti vytvárali komplexnejšie aplikácie, je vhodnejšie použiť napr. Databázu PostgreSQL alebo MySQL. Pre nás by avšak teraz predstavovali zbytočné úsilie navyše.
Modely
S databázou budeme pracovať pomocou tzv. ORM (Objektovo-Relačná
Mapovanie). To znamená, že budeme pracovať s objektmi, a toto počínanie
nám bude Django na pozadí automaticky prevádzať na databázové príkazy. K
vytvoreniu databázových tabuliek teda nespustíte zakladacia SQL príkazy, ako
ste možno boli zvyknutí, ale vytvoríme triedy reprezentujúci databázové
entity. Korešpondujúce tabuľky budú neskôr založené automaticky. Vytvorme
si entity Film
a Zanr
.
Prejdeme do súboru mysite/moviebook/models.py
a upravme jeho
obsah do nasledujúcej 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 réžiu, žánre majú filmy a názvy
žánrov. Okrem definícia textových stĺpcov tu vidíme aj definíciu cudzieho
kľúča, teda väzby medzi dvoma databázovými tabuľkami, v našom prípade
väzbu žánru na film. Všimnite si, že naše modely dedí z
models.Model
, vďaka tomu získajú napr. Metódu
save()
, ktorá ich inštancie umožní uložiť do databázy. To si
vyskúšame za chvíľu.
Migrácia
Úprave databázy tak, aby zodpovedala definícii modelov v našej aplikácii, sa hovorí migrácie. Tento proces musíme spustiť zakaždým, keď vykonáme zmenu v definícii dátové štruktúry a potrebujeme, aby Django na jej základe databázu upravilo, v našom prípade dokonca vytvorilo.
Databázovú migráciu najprv vytvoríme príkazom:
py manage.py makemigrations moviebook
Django nás odmení nasledujúcim výstupom:
C:\Users\David\AppData\Local\Programs\Python\mysite>py manage.py makemigrations moviebook Migrations for 'moviebook': moviebook\migrations\0001_initial.py - Create model Film - Create model Zanr
Potom migráciu spustíme:
py manage.py migrate
výstup:
C:\Users\David\AppData\Local\Programs\Python\mysite>py manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, moviebook, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying moviebook.0001_initial... OK Applying sessions.0001_initial... OK
Možno si spomínate, ako sme si hovorili, že Django poskytuje databázovú administráciu. Hneď sa k nej dostaneme. Teraz vytvoríme tzv. Superuser, administračného užívateľa, cez ktorého databáze budeme môcť spravovať:
py manage.py createsuperuser
Budete vyzvaní na zadanie mena, emailu a hesla, zadajte vhodné údaje:
C:\Users\David\AppData\Local\Programs\Python\mysite>py manage.py createsuperuser Username (leave blank to use 'david'): Email address: Password: Password (again): Superuser created successfully.
Django API
Teraz si ukážeme prácu s Django API, teda ako do databázy vkladať nové riadky ako objekty a ako objekty z databázy tiež získavať. Ukážky vykonáme v interaktívnom shellu, ktorý spustíme pomocou:
py manage.py shell
A do neho napíšeme nasledujúci kód:
from moviebook.models import Film, Zanr muj_film = Film(nazev="Strazci Galaxie", rezie="James Gunn") # Vytvoříme si nový film muj_film.nazev # Zobrazí název filmu muj_film.save() # Uloží film do DB Film.objects.all() # Zobrazí všechny existující filmy muj_film.zanr_set.all() # Zobrazí všechny žánry k danému filmu muj_film.zanr_set.create(nazev_zanru="Fantasy/Action") # Vytvoří nový žánr k tomuto filmu
Prvá časť kódu vytvorí inštanciu nového filmu. Ďalší riadok jeho
názov vypíše do konzoly a potom inštanciu metódou save()
do
databázy uložíme.
Druhá časť kódu získa všetky filmy z databázy, ktoré nám budú následne vypísané. Zobrazíme si tiež žánre filmu a žáner vytvoríme.
výstup:
C:\Users\David\AppData\Local\Programs\Python\mysite>py manage.py shell Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 07:18:10) [MSC v.1900 32 bit (In tel)] on win32 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from moviebook.models import Film, Zanr >>> muj_film = Film(nazev="Strazci Galaxie", rezie="James Gunn") # Vytvoríme si novy film >>> muj_film.nazev # Zobrazí název filmu 'Strazci Galaxie' >>> muj_film.save() # Ulozí film do DB >>> >>> Film.objects.all() # Zobrazí vsechny existující filmy <QuerySet [<Film: Film object (1)>]> >>> muj_film.zanr_set.all() # Zobrazí vsechny zánry k danému filmu <QuerySet []> >>> muj_film.zanr_set.create(nazev_zanru="Fantasy/Action") # Vytvorí novy zánr k tomuto filmu <Zanr: Zanr object (1)> >>>
Rozšírenie modelov
Upravme naše modely tak, aby nám vracali názov a meno režiséra. Podobne upravíme aj žáner.
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)
Ak ste stále v interaktívnom shellu, tak ho ukončite príkazom
quit()
a spustite novú reláciu príkazom
py manage.py shell
. Do shellu teraz 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:
>>> from moviebook.models import Film, Zanr >>> Film.objects.all() # Uvidíme název filmu i jméno reziséra <QuerySet [<Film: Nazev: Strazci Galaxie | Rezie: James Gunn>]> >>> muj_film = Film.objects.get(nazev="Strazci Galaxie") >>> muj_film.zanr_set.all() # Zobrazí informace o filmu a také název zánru <QuerySet [<Zanr: Film: Nazev: Strazci Galaxie | Rezie: James Gunn | Nazev_zanru : Fantasy/Action>]> >>>
Administrácia databázy
Konečne sa dostávame k administrácii. Superuser máme vytvoreného. Najprv
je potrebné naše modely do administrácie zaregistrovať. To vykonáme
úpravou súboru /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)
Nnyí si spustíme server a zamierime si to na adresu
http://localhost:8000/admin/
. Prihlasujeme sa ako superuser
údajmi, ktoré ste si predtým zvolili. Po prihlásení sa nám naskytne
takýto pohľad.
Ak ste všímaví, tak vás do očí udrie Films
a
Zanrs
, to zmeníme neskôr. Otvoríme entity "Films" a tam uvidíme
náš film s názvom "Strážcovia Galaxie". Všimnite si, že je nám
vypísaná návratová hodnota našej metódy __str__()
, ktorú sme
si vytrořili v /mysite/moviebook/models.py
, v prípade filmu teda
jeho názov, zvislou čiarou a réžia.
Ak si entitu (film) rozkliknite, môžeme tu editovať jeho názov a meno režiséra. Pre ukážku si vytvoríme ďalší ľubovoľný film (Films -> tlačidlo add Film vpravo hore). Potom si to namierite do sekcie "Zanrs" a zobrazíme si detail o našom súčasnom žánru. Ak sa pokúsite nastaviť žánru film, tak sa vám tiež zobrazí náš nový film, ako môžete pozorovať na nasledujúcom obrázku.
V aplikácii máme teraz chybu, bolo by totiž logické, aby sa film viazal
na žáner a nie naopak. Otvoríme si preto náš DB model u aplikácie
moviebook a reláciu zmeníme, pred týmto krokom odporúčam zmazať všetky
existujúce filmy a žánre. Aspoň si tým precvičíme prácu s databázou.
Odstránenie môžete vykonať jednoducho cez administráciu. Prejdeme do
súboru /mysite/moviebook/models.py
, ktorý upravíme do
nasledujúcej 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)
Ďalej je potrebné vykonané zmeny modelu "premietnuť do databázy", preto použijeme nasledujúce, už známe príkazy pre vytvorenie a spustenie migrácie.
py manage.py makemigrations moviebook py manage.py migrate
Teraz stačí server znovu spustiť a vyskúšať si, že všetko funguje. Ako prvý však musíme vytvoriť žáner, pretože sme zmenili vzťah medzi filmami a žánre ( "žánru"> "film") a film sa musí na nejaký žáner viazať, aby mohol byť vytvorený. Pridanie filmu potom vyzerá takto:
Výborne, všetko funguje ako má. Určite vás už tiež nebaví pozerať sa
na skomolené slová "Films" a "Zanrs" a preto si trošku upravíme modely
"Film" a "žáner". K tomu použijeme triedu Meta,
ktorá slúži na ukladanie / nastavenie informácií navyše, ako je v tomto
prípade názov množného čísla entity nastaviteľný pomocou
"verbose_name_plural". Súbor /mysite/moviebook/models.py
ešte
raz upravme:
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"
Namierime si to rovno do administrácie na
http://localhost:8000/admin/
, kde už môžeme pozorovať krásne a
českej pomenovanie našich modelov. V budúcej lekcii, Databázy filmov v Django - Generic Views a Formuláre , naprogramujeme
prácu s databázou cez našej aplikácie pomocou generic views.
Údaje pre Superuser pre databázu v priloženom projektu sú:
- meno: david
- heslo: heslojeveslo
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 114x (1.29 MB)
Aplikácia je vrátane zdrojových kódov v jazyku Python