Lekce 6 - Databáze filmů v Django - Databáze

Python Django Databáze filmů v Django - Databáze

Unicorn College ONEbit hosting Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

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ů. Zatím máme vytvořenou šablonu a data o filmu jsme jí předali jako list. Samozřejmě by bylo hezké mít data uložená v databázi a ne v listu, jak se na správnou webovou aplikaci sluší a patří. Právě databázi je věnován celý dnešní tutoriál.

Databáze

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. Pokud jste o ní ještě neslyšeli, nevadí, nutné minimum bude vysvětlené přímo zde v kurzu. Detailní práci s databázi se případně naučíte po navštívení uvedeného odkazu. Pokud byste v budoucnu vytvářeli komplexnější aplikace, je vhodnější použít např. databázi PostgreSQL nebo MySQL. Pro nás by ovšem nyní představovaly zbytečné úsilí navíc.

Modely

S databází budeme pracovat pomocí tzv. ORM (Objektově-Relační Mapování). To znamená, že budeme pracovat s objekty, a toto počínání nám bude Django na pozadí automaticky převádět na databázové příkazy. K vytvoření databázových tabulek tedy nespustíme zakládací SQL příkazy, jak jste možná byli zvyklí, ale vytvoříme třídy reprezentující databázové entity. Korespondující tabulky budou později založené automaticky. Vytvořme si entity Film a Zanr.

Přejdeme 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ěte si, že naše modely 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

Ú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:

py manage.py makemigrations moviebook

Django nás odmění následujícím výstupem:

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

Poté migraci 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žná si vzpomínáte, jak jsme si říkali, že Django poskytuje databázovou administraci. Hned se k ní dostaneme. Nyní vytvoříme tzv. superusera, administračního uživatele, přes kterého databázi budeme moci spravovat:

py manage.py createsuperuser

Budete vyzváni k zadání jména, emailu a hesla, zadejte 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

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

První část kódu vytvoří instanci nového filmu. Další řádek jeho název vypíše do konzole a poté instanci metodou save() do databáze uložíme.

Druhá část kódu získá všechny filmy z databáze, které nám budou následně vypsány. Zobrazíme si také žánry filmu a žánr vytvoří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šíření modelů

Upravme naše modely tak, aby nám vracely název a jméno režiséra. Podobně upravíme i žánr.

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 jste stále v interaktivním shellu, tak ho ukončete příkazem quit() a spusťte 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:

>>> 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>]>
>>>

Administrace databáze

Konečně se dostáváme k administraci. Superusera máme vytvořeného. Nejprve 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)

Nnyí si spustíme server a zamíříme si to na adresu http://localhost:8000/admin/. Přihlašujeme se jako superuser údaji, které jste si předtím zvolili. Po přihlášení se nám naskytne takovýto pohled.

Databázová administrace Django aplikace v Python

Pokud jste všímaví, tak vás 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 "Strázci Galaxie". Všimněte si, že je nám vypsána návratová hodnota naší metody __str__(), kterou jsme si vytroř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 Jango frameworku pro Python

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íte nastavit žánru film, tak se vám také zobrazí náš nový film, jak můžete 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áš DB model u aplikace moviebook a relaci změníme, před tímto krokem doporučuji smazat všechny stávající filmy a žánry. Alespoň si tím procvičíme práci s databází. Odstranění můžete 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ě vá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 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"

Namíříme si to rovnou do administrace na http://localhost:8000/admin/, kde již můžeme pozorovat krásné a české pojmenování našich modelů. V příští lekci, Databáze filmů v Django - Generic Views a Formuláře, naprogramujeme práci s databází přes naší aplikace pomocí generic views.

Údaje pro superusera pro databázi v přiloženém projektu jsou:

  • jméno: david
  • heslo: heslojeveslo

 

Stáhnout

Staženo 3x (777.83 kB)
Aplikace je včetně zdrojových kódů v jazyce Python

 

 

Článek pro vás napsal MQ .
Avatar
Jak se ti líbí článek?
5 hlasů
Autor je srdcem Pythonista.
Aktivity (2)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!