Zarábaj až 6 000 € mesačne! Akreditované rekvalifikačné kurzy od 0 €. Viac informácií.

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:

Databázová administrácia Django aplikácie v Python - Tvorba webov v Django frameworku pre Python

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:

Výpis entít v databázovej administrácii Django frameworku pre Python - Tvorba webov v Django frameworku pre Python

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:

Úprava entít v databázovej administrácii Django frameworku pre Python - Tvorba webov v Django frameworku pre Python

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:

Pridanie entity v databázovej administrácii Django frameworku pre Python. - Tvorba webov v Django frameworku pre Python

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/nas­tavenie 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

 

Predchádzajúci článok
Databáza filmov v Django - Založenie projektu a static files
Všetky články v sekcii
Tvorba webov v Django frameworku pre Python
Preskočiť článok
(neodporúčame)
Databáza filmov v Django - Generic Views a Formuláre
Článok pre vás napísal MQ .
Avatar
Užívateľské hodnotenie:
1 hlasov
Používám hlavně Python a zajímám se o Deep Learning a vše kolem.
Aktivity