Skip to content

Commit

Permalink
Rozwijanie scenariusza Django "Mały Bar – Pizza"
Browse files Browse the repository at this point in the history
  • Loading branch information
xinulsw committed Dec 27, 2016
1 parent 60f594a commit 296c600
Show file tree
Hide file tree
Showing 9 changed files with 392 additions and 235 deletions.
4 changes: 1 addition & 3 deletions docs/python/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ Python
###################

Wszystkie dotychczasowe scenariusze prezentujące zastosowania języka Python,
które przygotowywałem i zamieszczałem w tym repozytorium,
znajdziesz w dokumentacji `Python101 <http://python101.readthedocs.org>`_,
która towarzyszy projektowi `"Koduj z Klasą" <http://www.ceo.org.pl/pl/koduj>`_
które zamieszczane były początkowo w tym repozytorium, znajdziesz w dokumentacji `Python101 <http://python101.readthedocs.org>`_, która towarzyszy projektowi `"Koduj z Klasą" <http://www.ceo.org.pl/pl/koduj>`_
realizowanemu pod patronatem `Centrum Edukacji Obywatelskiej <http://www.ceo.org.pl/pl>`_.

.. toctree::
Expand Down
272 changes: 189 additions & 83 deletions docs/python/malybar/malybar.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ Opuszczenie środowiska umożliwia komenda ``deactivate``.

Polecenia ``pip install ...`` instalują wskazaną wersję Django oraz dodatkową aplikację
ułatwiającą zarządzanie użytkownikami. Tak zainstalowane moduły będą dostępne
tylko w akywowanym środowisku.
tylko w aktywowanym środowisku.

**Ćwiczenie**
Ćwiczenie
---------

Zgodnie z powyższym opisem przygotuj samodzielnie wirtualne środowisko do pracy z Django.

Expand All @@ -62,107 +63,228 @@ Zgodnie z powyższym opisem przygotuj samodzielnie wirtualne środowisko do prac
Projektując aplikację będziemy często korzystać z poleceń wydawanych w katalogu
:file:`dj_10_4` w terminalu. Nie zamykaj więc okna terminala.

Projekt, serwer, aplikacja
==========================
Projekt
========

Otwórz terminal, przejdź do katalogu z utworzonym wcześniej wirtualnym środowiskiem
:file:`dj_10_4` i aktywuj go. Utworzymy teraz projekt i uruchomimy serwer deweloperski.
Wydajemy polecenia:

.. code-block:: bash
~$ django-admin stratproject malybar
~$ cd malybar
~$ python manage.py runserver
~/dj_10_4$ django-admin stratproject malybar
~/dj_10_4$ cd malybar
~/dj_10_4/malybar$ python manage.py runserver
Tyle wystarczy, żeby utworzyć szkielet serwisu i uruchomić serwer deweloperski,
który możemy wywołać wpisując w przeglądarce adres: ``127.0.0.1:8000``.
Serwer zatrzymujemy naciskając w terminalu skrót :kbd:`CTRL+C`.
Większość zmian w kodzie nie wymaga restartowania serwera. W razie potrzeby
serwer zatrzymujemy naciskając w terminalu skrót :kbd:`CTRL+C`.

.. image:: img/django01.jpg

Poznajmy strukturę plików naszego projektu. W terminalu wydajemy jedno z poleceń:

.. code-block:: bash
~/dj_10_4/malybar$ tree
~/dj_10_4/malybar$ ls -R
.. figure:: img/django03.jpg

Nazwa zewnętrznego katalogu :file:`malybar` nie ma znaczenia, można ją dowolnie zmieniać,
to tylko pojemnik na projekt. Zawiera on:

- :file:`manage.py` – skrypt Pythona do zarządzania projektem;
- :file:`db.sqlite3` – bazę danych w domyślnym formacie SQLite3.

**Katlog projektu** :file:`malybar/malybar` zawiera:

- :file:`settings.py` – konfiguracja projektu;
- :file:`urls.py` – swego rodzaju "menu" naszego projektu, a więc lista wpisów
definiująca adresy URL, które będziemy obsługiwać;
- :file:`wsgi.py` – plik konfiguracyjny wykorzystywany przez serwery WWW.

Plik :file:`__init__.py` obecny w danym katalogu wskazuje, że dany katalog jest modułem Pythona.


Aplikacja
=========

W ramach jednego projektu (serwisu internetowego) może działać wiele aplikacji.
Pierwszą utworzymy poleceniem:
Utworzymy teraz naszą aplikację `pizza` i zobaczymy strukturę plików:

.. code-block:: bash
~/malybar$ python manage.py startapp pizza
~/dj_10_4/malybar$ python manage.py startapp pizza
~/dj_10_4/malybar$ tree pizza
lub:
~/dj_10_4/malybar$ ls -R pizza
– w wyniku jego działania w katalogu :file:`pizza` powstanie szkielt aplikacji.
**Katalog aplikacji** :file:`malybar/pizza` zawiera:

.. tip::
- :file:`apps.py` – ustawienia aplikacji;
- :file:`admin.py` – konfigurację panelu administracyjnego;
- :file:`models.py` – plik definiujący modele danych przechowywanych w bazie;
- :file:`views.py` – plik zawierający funkcje lub klasy definiujące tzw. *widoki* (ang. *views*), obsługujące żądania klienta przychodzące do serwera;

Katalog :file:`malybar` będziemy nazywać **katalogiem projektu**, natomiast katalog
:file:`pizza` – **katalogiem aplikacji**.

Zajrzyjmy do katalogu naszego projektu. W terminalu wydajemy polecenie ``tree`` lub
jeżeli go nie ma ``ls -R``.
Ustawienia projektu
===================

.. figure:: img/django03.jpg
Otwieramy i edytujemy plik :file:`malybar/settings.py`.

.. note::
**Dostępne w projekcie aplikacje** znajdują się w liście ``INSTALLED_APPS``. Domyślnie Django udostępnia
kilka obsługujących podstawowe funkcjonalności serwisu internetowego. Na początku tej listy
dodamy konfigurację aplikacji `pizza`, a na końcu zainstalowanej wcześniej `django-registration`:

Katlog projektu :file:`malybar` zawiera:

- bazę, czyli plik :file:`db.sqlite3`; domyślnym systemem bazodanowym jest SQLite3;
- skrypt Pythona :file:`manage.py` służy do zarządzania projektem;
- :file:`settings.py` – zawiera konfigurację projektu;
- :file:`urls.py` – to swego rodzaju menu naszego projektu, a więc lista wpisów
definiująca adresy URL dostępne w naszym projekcie;
- :file:`wsgi.py` – plik konfiguracyjny wykorzystywany przez serwery WWW.
.. raw:: html

<div class="code_no">Kod nr <script>var code_no = code_no || 1; document.write(code_no++);</script>: <i>malybar/settings.py</i></div>

W katalogu aplikacji :file:`pizza` znajdziemy:
.. highlight:: python
.. literalinclude:: malybar/settings.py
:linenos:
:lineno-start: 33
:lines: 33-42
:emphasize-lines: 2, 9

- :file:`apps.py` – ustawienia aplikacji;
- :file:`admin.py` – konfigurację panelu administracyjnego;
- :file:`models.py` – plik definiujący modele danych przechowywanych w bazie;
- :file:`views.py` – plik zawierający funkcje, tzw. *widoki*, obsługujące zdefiniowane
w plikach :file:`urls.py` adresy.
**Lokalizacja projektu** obejmuje ustawienie języka i strefy czasowej:

Wszystkie katalogi zawierają również plik :file:`__init__.py` wskazujący, że dany
katalog jest modułem Pythona.
.. raw:: html

Po utworzeniu szkieletu aplikacji wykonujemy opisane niżej czynności.
<div class="code_no">Kod nr <script>var code_no = code_no || 1; document.write(code_no++);</script>: <i>malybar/settings.py</i></div>

1. Edytujemy plik ustawień projektu :file:`malybar/settings.py`, a w nim:
- rejestrujemy aplikację pizza dopisując jej konfigurację do listy INSTALLED_APPS;
przy okazji widzimy, że domyślnie na liście znajdują się już aplikacje dostarczane
przez framework;
- ustawiamy polską strefę czasową i polski język
.. highlight:: python
.. literalinclude:: malybar/settings.py
:linenos:
:lineno-start: 108
:lines: 108-110

.. code-block:: python

INSTALLED_APPS = [
'pizza.apps.PizzaConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
...
LANGUAGE_CODE = 'pl'
TIME_ZONE = 'Europe/Warsaw'
...
**Konfiguracja adresów URL projektu** zawarta jest w pliku :file:`malybar/urls.py`. Każda aplikacja definiuje
zazwyczaj swoją listę obsługiwanych adresów, którą należy dołączyć:

2. Włączamy mapowanie adresów aplikacji pizza do pliku projektu :file:`malybar/urls.py`:

.. code-block:: python
.. raw:: html

urlpatterns = [
url(r'^', include('pizza.urls', namespace='pizza')),
url(r'^pizza/', include('pizza.urls', namespace='pizza')),
url(r'^admin/', admin.site.urls),
]
<div class="code_no">Kod nr <script>var code_no = code_no || 1; document.write(code_no++);</script></div>

wyjaśninie funkcji ``url()``, parametry obowiązkowe to `regex` i `view`, opcjonalne `kwargs` i `name`
- ponownie uruchomić serwer
.. highlight:: python
.. literalinclude:: malybar/urls_01.py
:linenos:
:lineno-start: 16
:lines: 16-24
:emphasize-lines: 3, 6-7

Dostęp do aplikacji możesz zweryfikować wpisując adres: ``127.0.0.1:8000/moja_apl``.
Funkcja ``include()`` jako pierwszy parametr przyjmuje ścieżkę dostępu do konfiguracji adresów danej
aplikacji. W praktyce jest to nazwa katalogu, w którym znajduje się aplikacja, operator ``.`` (kropka)
oraz domyślna nazwa pliku konfiguracyjnego :file:`urls.py` bez rozszerzenia.
Wartość parametru ``namespace`` definiuje przestrzeń nazw, w której dostępne będą adresy używane w aplikacji.

[zrzut]
Widok domyślny
==============

**Mapowanie adresów URL aplikacji** tworzymy w nowym pliku :file:`pizza/urls.py`,
który wypełniamy następującym kodem:

.. raw:: html

<div class="code_no">Kod nr <script>var code_no = code_no || 1; document.write(code_no++);</script></div>

.. highlight:: python
.. literalinclude:: pizza/urls_01.py
:linenos:
:lineno-start: 1
:lines: 1-
:emphasize-lines: 2, 5


Lista ``urlpatterns`` zawiera powiązania między adresami URL a obsługującymi je widokami
zapisanymi w pliku :file:`views.py`, który importujemy w drugiej linii.

Funkcja ``url()`` przyporządkowuje adresowi URL widok, który go obsługuje. Pierwszy parametr to wyrażenie
regularne, do którego Django próbuje dopasować adres otrzymany w żądaniu od klienta. Drugi to nazwa widoku.
Trzeci to unikalna nazwa, dzięki której można odwoływać się w aplikacji do zdefiniowanego adresu.

**Widok** definiuje jakiś typ strony WWW, za pomocą którego użytkownik wykonuje w aplikacji
jakieś operacje, np. wyświetla zestawienie danych. Technicznie widok zazwyczaj składa się
z funkcji otrzymującej żądanie klienta i jakiegoś szablonu służącego prezentowaniu danych.

Widok domyślny obsługujący żądania typu GET przychodzące na adres podstawowy serwera
zdefiniujemy w pliku :file:`pizza/views.py`:

.. raw:: html

<div class="code_no">Kod nr <script>var code_no = code_no || 1; document.write(code_no++);</script></div>

.. highlight:: python
.. literalinclude:: pizza/views_01.py
:linenos:
:lineno-start: 1
:lines: 1-


.. warning::

Linia ``# -*- coding: utf-8 -*-`` to określenie kodowania znaków.
Należy umieszczać je w pierwszej linii każdego pliku, w którym zamierzamy używać polskich
znaków, czy to w komentarzach czy w kodzie.



Nazwa funkcji – ``index()`` – jest umowna. Każdy widok otrzymuje szczegóły żądania wysłanego przez klienta
(obiekt typu ``HttpRequest``) i powinien zwrócić jakąś odpowiedź (``HttpResponse``).
W tym wypadku zwracamy funkcję ``render()`` wywołującą wskazany jako drugi parametr szablon,
który otrzymuje dane w postaci słownika ``kontekst`` (nazwa umowna).


**Szablon** (ang. *template*) – to plik tekstowy, służący generowaniu najczęściej plików HTML.
Oprócz tagów HTML-a, zawiera zmienne oraz tagi sterujące języka szablonów Django.

.. note::

Szablony umieszczamy w katalogu: :file:`pizza/templates/pizza`!

Zawartość szablonu :file:`index.html`:

.. raw:: html

<div class="code_no">Kod nr <script>var code_no = code_no || 1; document.write(code_no++);</script></div>

.. highlight:: python
.. literalinclude:: pizza/templates/pizza/index_01.html
:linenos:
:lineno-start: 1
:lines: 1-


Zobacz, jak w znaczniku ``<p>`` wstawiamy przekazaną do szablonu zmienną ``komunikat``,
używamy podwójnych nawiasów sześciennych: ``{{ nazwa_zmiennej }}``.


.. tip::

W tym miejscu warto usystematyzować dodawanie kolejnych funkcji do naszej aplikacji.
**Zazwyczaj** proces ten przebiega wg. schematu:

1) w pliku :file:`urls.py`: przyporządkowujemy adres widokowi;
2) w pliku :file:`views.py`: definiujemy widok, który najczęściej zwraca szablon połączony z przekazanymi do nego danymi;
3) w katalogu :file:`templates/nazwa_aplikacji`: tworzymy szablon, który łączy znaczniki HTML-a i dane.


Test widok domyślnego
---------------------

W tym momencie powinieneś przetestować działanie aplikacji. Sprawdź, czy działa serwer. Jeżeli
nie, uruchom go. W przeglądarce odśwież lub wpisz adres domyślny serwera testowego, tj.:
``127.0.0.1:8000``. Powinieneś zobaczyć nazwę projektu i powitanie.

W przypadku błędów Django wyświetla obszerne informacje, które na pierwszy rzut oka
są bardzo skomplikowane. Nie musisz studiować całości, żeby zrozumieć, co poszło nie tak.
Skup się na początku komunikatu!

Model danych
============
Expand All @@ -171,25 +293,9 @@ Django jest wyposażone we własny system ORM (ang.), służący zarówno do def
jak i zarządzania źródłami danych.

W pliku :file:`moja_apl/models.py` definiujemy klasę(y) opisującą(e) źródła danych aplikacji.
Odpowiadają one tablom w bazie danych. Każda klasa zawiera pola opisujące przechowywane w nich
Odpowiadają one tabelom w bazie danych. Każda klasa zawiera pola opisujące przechowywane w nich
informacje. Pola odpowiadają kolumnom w tabelach.

Po zdefiniowaniu modelu danych należy go aktywować, co wymaga włączenia aplikacji do naszej strony. Uzupełniamy więc listę ``INSTALLED_APPS`` w pliku :file:`moja_str/settings.py`, która
na początku zawiera już kilka domyślnie włączonych aplikacji. Dodajemy do niej ścieżkę do ustawień naszej:

.. code-block:: python
INSTALLED_APPS = [
'moja_apl.apps.PollsConfig', # podświetlenie
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
Następnie tworzymy tzw. *migrację*, czyli informację o zmianie modelu naszej aplikacji.

.. code-block:: bash
Expand Down Expand Up @@ -255,11 +361,11 @@ go automatycznie. Na początku tworzymy konto administratora:
$ python manage.py createsuperuser
Django zapyta o nazwę, e-mail i hasło. Podajemy: “admin”, “” (pomijamy), “admin”.
Jeżeli chcemy mieć możliwość dodawania treści, w pliku :file:`moja_apl/admin.py`
Jeżeli chcemy mieć możliwość dodawania treści, w pliku :file:`pizza/admin.py`
importujemy nasz(e) model(e) i rejestrujemy go(je):

.. highlight:: python
.. literalinclude:: admin_01.py
.. literalinclude:: pizza/admin_01.py
:linenos:
:lineno-start: 1
:lines: 1-
Expand Down

0 comments on commit 296c600

Please sign in to comment.