Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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:

Databázová administrace Django aplikace v Python - Django - Tvorba webů v Pythonu

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:

Výpis entit v databázové administraci Django frameworku pro Python - Django - Tvorba webů v Pythonu

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:

Úprava entit v databázové administraci Django frameworku pro Python - Django - Tvorba webů v Pythonu

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:

Přidání entity v databázové administraci Django frameworku pro Python. - Django - Tvorba webů v Pythonu

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_plu­ral". 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 110x (1.29 MB)
Aplikace je včetně zdrojových kódů v jazyce Python

 

Předchozí článek
Databáze filmů v Django - Vytvoření projektu a static files
Všechny články v sekci
Django - Tvorba webů v Pythonu
Přeskočit článek
(nedoporučujeme)
Databáze filmů v Django - Generic Views a Formuláře
Článek pro vás napsal MQ .
Avatar
Uživatelské hodnocení:
77 hlasů
Používám hlavně Python a zajímám se o Deep Learning a vše kolem.
Aktivity