6. diel - Databáza filmov v Django - Databáza
V minulej lekcii, Databáza filmov v Django - Založenie projektu a static files, sme začali tvorbu nového projektu, ktorým je webová databáza filmov.
V nasledujúcom tutoriále webových aplikácií s frameworkom Django v Pythone pokročíme v tvorbe našej aplikácie - Filmovej databázy. Zatiaľ máme v aplikácii vytvorenú šablónu a dáta o filme sme jej odovzdali ako zoznam. Samozrejme by bolo pekné mať dáta uložené v databáze, ako sa na správnu webovú aplikáciu pristane a patrí. A práve na databázu sa teraz zameriame. Vysvetlíme si ORM prístup, vytvoríme modely pre filmy a ich žánre, databázu zmigrujeme a naučíme sa pracovať s Django administráciou.
Databázy a Django
Ako databázu budeme používať SQLite, ktorá je v Django už prednastavená a nemusí sa na rozdiel od iných databáz inštalovať ani konfigurovať. Nutné minimum znalostí a základy práce s ňou si vysvetlíme priamo tu v kurze. Pokiaľ by sme však v budúcnosti vytvárali komplexnejšie aplikácie, je vhodnejšie použiť napr. databázu PostgreSQL alebo MySQL. Pre nás by ale teraz predstavovali zbytočné úsilie navyše.
Objektovo relačné mapovanie
S databázou budeme pracovať pomocou tzv. ORM – objektovo
relačného mapovania. Znie to síce veľmi odborne, ale v skutočnosti nám
tento prístup výrazne uľahčí prácu. My totiž budeme pracovať s objektmi
a Django ich bude sám na pozadí automaticky prevádzať na databázové
príkazy. Na vytvorenie databázových tabuliek nám teda postačí vytvoriť
triedy reprezentujúce databázové entity. Korešpondujúce tabuľky budú
neskôr založené automaticky. Ideme na to Vytvorme si triedy
Movie
a Genre
.
Prejdime do súboru mysite\moviebook\models.py
a upravme jeho
obsah do nasledujúcej podoby:
from django.db import models class Movie(models.Model): title = models.CharField(max_length=200) director = models.CharField(max_length=180) class Genre(models.Model): movie = models.ForeignKey(Movie, on_delete=models.CASCADE) genre_name = models.CharField(max_length=80)
Vidíme, že filmy majú názvy a réžiu, žánre majú filmy a názvy
žánrov. Okrem definície 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šimnime si tiež, že naše triedy dedia 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 databázy
Úprave databázy tak, aby zodpovedala definícii modelov v našej aplikácii, sa hovorí migrácia. Tento proces musíme spustiť zakaždým, keď vykonáme zmenu v definícii dátovej š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 v termináli v priečinku
mysite/
:
py manage.py makemigrations moviebook
Django nás odmení nasledujúcim výstupom:
Creating migration: Migrations for 'moviebook': moviebook\migrations\0001_initial.py - Create model Movie - Create model Genre
Potom migráciu spustíme:
py manage.py migrate
Výstupom bude:
Running migration: Operations to perform: Apply all migrations: admin, auth, contenttypes, moviebook, sessions Running migrations: Applying moviebook.0001_initial... OK
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 taktiež 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 Movie, Genre my_movie = Movie(title="Guardians of the Galaxy", director="James Gunn") # Creates a new movie my_movie.save() # Saves the movie to the database my_movie.genre_set.create(genre_name="Fantasy/Action") # Creates a new genre for this movie genre_name = my_movie.genre_set.first().genre_name # Gets the genre for a specific movie instance
Shell ho vykoná bez viditeľného výstupu. Presvedčíme sa teda, že všetko prebehlo ako malo. Do shellu vložíme postupne tieto dva príkazy:
my_movie.title # Shows the movie title genre_name # Shows the genre name
Vo výstupe vidíme film aj žáner:
Displaying database objects: In [2]: my_movie.title Out[2]: 'Guardians of the Galaxy' In [3]: genre_name Out[3]: 'Fantasy/Action'
Rozšírenie modelov
Upravme teraz naše triedy v modeli tak, aby nám vracali názov a meno režiséra a názov žánru:
from django.db import models class Movie(models.Model): title = models.CharField(max_length=200) director = models.CharField(max_length=180) def __str__(self): return "Title: {0} | Director: {1}".format(self.title, self.director) class Genre(models.Model): movie = models.ForeignKey(Movie, on_delete=models.CASCADE) genre_name = models.CharField(max_length=80) def __str__(self): return "Movie: {0} | Genre_name: {1}".format(self.movie, self.genre_name)
Pokiaľ sme stále v interaktívnom shellu, tak ho ukončíme príkazom
quit()
a spustíme novú reláciu príkazom
py manage.py shell
. Do shellu teraz vložíme:
from moviebook.models import Movie, Genre Movie.objects.all() # Shows the movie title and the director's name my_movie = Movie.objects.get(title="Guardians of the Galaxy") my_movie.genre_set.all() # Shows information about the movie and also the genre name
Výstup v konzole:
Listing database records:
<QuerySet [<Genre: Movie: Title: Guardians of the Galaxy | Director : James Gunn | Genre_name: Fantasy/Action>]>
Administrácia databázy
Napokon sa dostávame k administrácii. Vytvoríme si tzv. superužívateľa (administračného užívateľa) cez ktorého databázu budeme môcť spravovať. Do konzoly zadáme:
py manage.py createsuperuser
Budeme vyzvaní na zadanie mena, emailu a hesla, zadajte vhodné údaje:
Creating a superuser:
Username (leave blank to use 'tomse'):
Email address:
Password:
Password (again):
Superuser created successfully.
Superživateľa máme vytvoreného. Teraz je potrebné naše modely do
administrácie zaregistrovať. To urobíme úpravou súboru
\mysite\moviebook\admin.py
:
from django.contrib import admin from .models import Movie, Genre # Importing the models # Registering the models admin.site.register(Movie) admin.site.register(Genre)
Teraz si spustíme server a zamierime si to na adresu
http://localhost:8000/admin/
. Prihlasujeme sa ako superužívateľ
údajmi, ktoré sme si predtým zvolili. Po prihlásení sa nám naskytne
nasledujúci pohľad:
Všímavé do očí udrú Movies
a Genres
(automatické prevedenie názvu entity do množného čísla), o chvíľu si
ukážeme, ako to v prípade potreby môžeme zmeniť. Otvoríme entity
Movies
a tam uvidíme náš film s názvom
Guardians of the Galaxy
. Všimnime si, že je nám vypísaná
návratová hodnota našej metódy __str__()
, ktorú sme si
vytvorili v \mysite\moviebook\models.py
, v prípade filmu teda jeho
názov, zvislítko a réžia:
Pokiaľ si entitu (Movie
) rozklikneme, môžeme tu editovať
jeho názov a meno režiséra. Pre ukážku si vytvoríme ďalší ľubovoľný
film (Movies
-> tlačidlo Add Movie
vpravo hore).
Potom si to namierime do sekcie Genres
a zobrazíme si detail o
našom súčasnom žánri. Pokiaľ sa pokúsime nastaviť žánru film, tak sa
nám tiež zobrazí náš nový film, ako môžeme 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áš databázový model pri
aplikácii moviebook
a reláciu zmeníme, pred týmto krokom
najlepšie zmažme všetky existujúce filmy a žánre. Aspoň si tým
precvičíme prácu s databázou. Odstránenie môžeme 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 Genre(models.Model): genre_name = models.CharField(max_length=80) def __str__(self): return "Genre_name: {0}".format(self.genre_name) class Movie(models.Model): title = models.CharField(max_length=200) director = models.CharField(max_length=180) genre = models.ForeignKey(Genre, on_delete=models.SET_NULL, null=True) def __str__(self): return "Title: {0} | Director: {1} | Genre: {2}".format(self.title, self.director, self.genre.genre_name)
Ď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 znova 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 žánrami (genre
> movie
) a film sa musí
na nejaký žáner viazať, aby mohol byť vytvorený. Pridanie filmu potom
vyzerá takto:
Výborne, všetko funguje, ako má. V prípade, že budeme chcieť, aby sa
tabuľky v množnom čísle nevolali Movies
a Genres
(napríklad keby sme mali názvy entít v slovenčine a chceli zabrániť
skomoleniu názvov ako Films
alebo Zaners
), mohli by
sme trochu upraviť modely Movie
a Genre
. Na to by sme
použili triedu Meta
, ktorá slúži na ukladanie/nastavenie
dodatočných informácií, 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
by sme upravili nasledovne:
from django.db import models class Genre(models.Model): genre_name = models.CharField(max_length=80, verbose_name="Genre") def __str__(self): return "Genre_name: {0}".format(self.genre_name) class Meta: verbose_name = "Genre" verbose_name_plural = "Genre_Entities" class Movie(models.Model): title = models.CharField(max_length=200, verbose_name="Movie title") director = models.CharField(max_length=180, verbose_name="Director") genre = models.ForeignKey(Genre, on_delete=models.SET_NULL, null=True, verbose_name="Genre") def __str__(self): return "Title: {0} | Director: {1} | Genre: {2}".format(self.title, self.director, self.genre.genre_name) class Meta: verbose_name = "Movie" verbose_name_plural = "Movie_Entities"
Namierime si to rovno do administrácie na
http://localhost:8000/admin/
, kde už môžeme pozorovať zmenený
názov našich našich modelov.
Údaje pre superužívateľov pre databázu v priloženom projekte sú nasledujúce: Username: Charles, Password: abc123
V ďalšej lekcii, Databáza filmov v Django - Generic Views a Formuláre, naprogramujeme prácu s databázou cez našej aplikácie pomocou generic views.
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é 4x (1.3 MB)
Aplikácia je vrátane zdrojových kódov v jazyku Python