8.3. Czat (cz. 3)

Poniższy materiał koncentruje się na obsłudze szablonów (ang. templates) wykorzystywanych w Django. Stanowi kontynuację projektu zrealizowanego w scenariuszu Czat (cz. 2).

Na początku pobierz archiwum z potrzebnymi plikami i rozpakuj je w katalogu domowym użytkownika. Następnie wydaj polecenia:

Terminal nr
~$ source pve3/bin/activate
(pve3) ~$ cd czat3
(pve3) ~/czat3$ python manage.py check

Ostrzeżenie

Przypominamy, że pracujemy w wirtualnym środowisku Pythona z zainstalowanym frameworkiem Django, które powinno znajdować się w katalogu pve3. Zobacz w scenariuszu Czat (cz. 1), jak utworzyć takie środowisko.

8.3.1. Szablony

Zapewne zauważyłeś, że większość kodu w szablonach i stronach HTML, które z nich powstają, powtarza się albo jest bardzo podobna. Biorąc pod uwagę schematyczną budowę stron WWW jest to nieuniknione.

Szablony, jak można było zauważyć, składają się ze zmiennych i tagów. Zmienne, które ujmowane są w podwójne nawiasy sześciokątne {{ zmienna }}, zastępowane są konkretnymi wartościami. Tagi z kolei, oznaczane notacją {% tag %}, tworzą mini-język szablonów i pozwalają kontrolować logikę budowania treści. Najważniejsze tagi, {% if warunek %}, {% for wyrażenie %}, {% url nazwa %} – już stosowaliśmy.

Spróbujmy uprościć i ujednolicić nasze szablony. Zacznijmy od szablonu bazowego, który umieścimy w pliku templates/czat/baza.html:

Plik baza.html. Kod nr
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!-- templates/czat/baza.html -->
<!DOCTYPE html>
<html lang="pl">
  <meta charset="utf-8" />
  <head>
    <title>{% block tytul %} System wiadomości Czat {% endblock tytul %}</title>
  </head>
  <body>
    <h1>{% block naglowek %} Witaj w aplikacji Czat! {% endblock %}</h1>

    {% block komunikaty %}
      {% if messages %}
        <ul>
          {% for komunikat in messages %}
            <li>{{ komunikat|capfirst }}</li>
          {% endfor %}
        </ul>
      {% endif %}
    {% endblock %}

    {% block tresc %} {% endblock %}

    {% if user.is_authenticated %}
      {% block linki1 %} {% endblock %}
      <p><a href="{% url 'czat:wyloguj' %}">Wyloguj się</a></p>
    {% else %}
      {% block linki2 %} {% endblock %}
    {% endif %}

    {% block linki3 %} {% endblock %}

  </body>
</html>

Jest to zwykły tekstowy dokument, zawierający schemat strony utworzony z wymaganych znaczników HTML oraz bloki zdefiniowane za pomocą tagów {% block %}. W pliku tym umieszczamy wspólną strukturę stron w serwisie (np. nagłówek, menu, sekcja treści, stopka itp.) oraz wydzielamy bloki, których treść będzie można zmieniać w szablonach konkretnych stron.

Wykorzystując szablon podstawowy, zmieniamy stronę główną, czyli plik index.html:

Plik index.html. Kod nr
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!-- templates/czat/index.html -->
{% extends "czat/baza.html" %}

{% block naglowek %}Witaj w aplikacji Czat!{% endblock %}

{% block linki1 %}
  <p>Jesteś zalogowany jako {{ user.username }}.</p>
  <p><a href="{% url 'czat:dodaj' %}">Dodaj wiadomość</a></p>
  <p><a href="{% url 'czat:wiadomosci' %}">Lista wiadomości</a></p>
{% endblock %}

{% block linki2 %}
  <p><a href="{% url 'czat:loguj' %}">Zaloguj się</a></p>
  <p><a href="{% url 'czat:rejestruj' %}">Zarejestruj się</a></p>
{% endblock %}

Jak widać, szablon dziedziczy z szablonu bazowego – tag {% extends plik_bazowy %}. Dalej podajemy zawartość bloków, które są potrzebne na danej stronie.

Postępując na tej samej zasadzie modyfikujemy szablon rejestracji:

Plik rejestruj.html. Kod nr
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- templates/czat/rejestruj.html -->
{% extends "czat/baza.html" %}

{% block naglowek %}Rejestracja użytkownika{% endblock %}

{% block tresc %}
  {% if not user.is_authenticated %}
    <form method="POST">
      {% csrf_token %}
      {{ form.as_p }}
      <button type="submit">Zarejestruj</button>
    </form>
  {% endif %}
{% endblock %}

{% block linki1 %}
  <p>Jesteś już zarejestrowany jako {{ user.username }}.</p>
{% endblock %}

{% block linki3 %}
  <p><a href="{% url 'czat:index' %}">Strona główna</a></p>
{% endblock %}

8.3.1.1. Ćwiczenie

Wzorując się na podanych przykładach zmień pozostałe szablony tak, aby opierały się na szablonie bazowym. Następnie przetestuj działanie aplikacji. Wygląd stron nie powinien ulec zmianie!

Dla przykładu szablon wiadomosc_list.html powinien wyglądać tak:

Plik wiadomosc_list.html. Kod nr
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!-- czat/wiadomosc_list.html -->
{% extends "czat/baza.html" %}

{% block naglowek %}Wiadomości{% endblock %}

{% block tresc %}
  <h2>Lista wiadomości:</h2>
  <ol>
    {% for wiadomosc in wiadomosci %}
    <li>
      <strong>{{ wiadomosc.autor.username }}</strong> ({{ wiadomosc.data_pub }}):
      <br /> {{ wiadomosc.tekst }}
      {% if wiadomosc.autor.username == user.username %}
        &bull; <a href="{% url 'czat:edytuj' wiadomosc.id %}">Edytuj</a>
        &bull; <a href="{% url 'czat:usun' wiadomosc.id %}">Usuń</a>
      {% endif %}
    </li>
    {% endfor %}
  </ol>

  {% if is_paginated %}
    <p>
    {% if page_obj.has_previous %}
      <a href="?page={{ page_obj.previous_page_number }}">Poprzednie</a>
    {% endif %}
      Strona {{ page_obj.number }} z {{ page_obj.paginator.num_pages }}.
    </span>
    {% if page_obj.has_next %}
      <a href="?page={{ page_obj.next_page_number }}">Następne</a>
    {% endif %}
    </p>
  {% endif %}
{% endblock %}

{% block linki3 %}
  <p><a href="{% url 'czat:index' %}">Strona główna</a></p>
{% endblock %}

8.3.2. Style CSS i obrazki

Nasze szablony zyskały na zwięzłości i przejrzystości, ale nadal pozbawione są elementarnych dla dzisiejszych stron WWW zasobów, takich jak style CSS, skrypty JavaScript czy zwykłe obrazki. Jak je dołączyć?

Przede wszystkim potrzebujemy osobnego katalogu czat/static/czat. W terminalu w katalogu projektu (!) wydajemy polecenia:

Terminal. Kod nr
(.pve) ~/czat3$  mkdir -p czat/static/czat
(.pve) ~/czat3$  cd czat/static/czat
(.pve) ~/czat3/czat/static/czat$ mkdir css js img

Ostatnie polecenie tworzy podkatalogi dla różnych typów zasobów:

  • css – arkusze stylów CSS,
  • js – skrypty Java Script,
  • img – obrazki.

Tworzymy przykładowy arkusz stylów CSS style.css i zapisujemy w katalogu static/czat/css:

Plik style.css. Kod nr
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
body {
	margin: 10px;
	font-family: Helvetica, Arial, sans-serif;
	font-size: 12pt;
	background: lightgreen url('../img/django.png') no-repeat fixed top right;
}
a { text-decoration: none; }
a:hover { text-decoration: underline; }
a:visited { text-decoration: none; }
.clearfix { clear: both; }
h1 { font-size: 1.8em; font-weight: bold; margin-top: 20px; }
h2 { font-size: 1.4em; font-weight: bold; margin-top: 20px; }
p { font-szie: 1em; font-family: Arial, sans-serif; }
.fr { float: right; }

Do podkatalogu static/czat/img rozpakuj obrazki z pobranego archiwum.

Teraz musimy dołączyć style i obrazki do szablonu bazowego baza.html:

Plik baza.html. Kod nr
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!-- templates/czat/baza.html -->
{% load staticfiles %}
<!DOCTYPE html>
<html lang="pl">
  <meta charset="utf-8" />
  <head>
    <title>{% block tytul %} System wiadomości Czat {% endblock tytul %}</title>
    <!-- dołączamy arkusz stylów: -->
    <link rel="stylesheet" type="text/css" href="{% static 'czat/css/style.css' %}" />
  </head>
  <body>
    <h1>{% block naglowek %} Witaj w aplikacji Czat! {% endblock %}</h1>

    {% block komunikaty %}
      {% if messages %}
        <ul>
        {% for komunikat in messages %}
          <li>{{ komunikat|capfirst }}</li>
        {% endfor %}
        </ul>
      {% endif %}
    {% endblock %}

    {% block tresc %} {% endblock %}

    {% if user.is_authenticated %}
      {% block linki1 %} {% endblock %}
      <p><a href="{% url 'czat:wyloguj' %}">Wyloguj się</a></p>
    {% else %}
      {% block linki2 %} {% endblock %}
    {% endif %}

    {% block linki3 %} {% endblock %}

    <!-- wstawiamy obrazki: -->
    <div id="obrazki">
      <img src="{% static 'czat/img/python.png' %}" width="300" />
      <img src="{% static 'czat/img/sqlite.png' %}" width="300" />
    </div>

  </body>
</html>
  • {% load staticfiles %} – ten kod umieszczamy na początku dokumentu, konfiguruje on ścieżkę do zasobów;
  • {% static plik %} – ten tag wskazuje lokalizację dołączanego do strony pliku, np. arkusza CSS czy obrazka, tag umieszczamy jako wartość atrybutu href.
../../_images/django_style.png

8.3.2.1. Ćwiczenie

W szablonie bazowym stwórz blok umożliwiający zastępowanie domyślnych obrazków. Następnie zmień szablon rejestracja.html tak, aby wyświetlał inne obrazki, które znajdziesz w podkatalogu czat/static/img.

Wskazówka

Tag {% load staticfiles %} musisz wstawić zaraz po tagu {% extends %} do każdego szablonu, w którym chcesz odwoływać się do plików z katalogu static.

../../_images/django_obrazki.png

8.3.3. Java Script

Na ostatnim zrzucie widać wykonane ćwiczenie, czyli użycie dodatkowych obrazków. Jednak strona nie wygląda dobrze, ponieważ treść podpowiedzi nachodzi na logo Django (oczywiście przy małym rozmiarze okna przeglądarki). Spróbujemy temu zaradzić.

Wykorzystamy prosty skrypt wykorzystujący bibliotekę jQuery. Ściągamy archiwum i rozpakowujemy do katalogu static/js. Następnie do szablonu podstawowego baza.html dodajemy przed tagiem zamykającym </body> znaczniki <script>, w których wskazujemy położenie skryptów:

Plik baza.html. Kod nr
1
2
    <script type="text/javascript" src="{% static 'czat/js/jquery.js' %}"></script>
    <script type="text/javascript" src="{% static 'czat/js/czat.js' %}"></script>

Po odświeżeniu adresu /rejestruj powinieneś zobaczyć poprawioną stronę:

../../_images/django_jscript.png

8.3.4. Bootstrap

Bootstrap to jeden z najpopularniejszych frameworków, który z wykorzystaniem języków HTML, CSS i JS ułatwia tworzenie responsywnych aplikacji sieciowych. Zintegrowanie go z naszą aplikacją przy wykorzystaniu omówionych mechanizmów jest całkiem proste.

Wchodzimy na stronę Getting started, kopiujemy linki dołączające arkusze CSS i wklejamy je za znacznikiem <title> w szablonie bazowym:

Plik baza.html. Kod nr
1
2
3
4
5
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <!-- Optional theme -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

Następnie kopiujemy link dołączający Java Script i wklejamy na końcu szablonu bazowego po linku włączającym jQuery.

Plik baza.html. Kod nr
1
2
3
4
    <script type="text/javascript" src="{% static 'czat/js/jquery.js' %}"></script>
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <script type="text/javascript" src="{% static 'czat/js/czat.js' %}"></script>

Na koniec użyjemy dla przykładu klas img-thumbnail i img-circle Bootstrapa w znacznikach <img> szablonu bazowego:

Plik baza.html. Kod nr
1
2
      <img src="{% static 'czat/img/python.png' %}" width="300" class="img-thumbnail img-circle" />
      <img src="{% static 'czat/img/sqlite.png' %}" width="300" class="img-thumbnail img-circle" />
../../_images/django_bootstrap.png

Informacja

Można oczywiście dołączać pliki Bootstrapa po pobraniu i umieszczeniu ich w podkatalogach folderu static za pomocą omawianego tagu {% static %}.

8.3.5. Materiały

  1. O Django http://pl.wikipedia.org/wiki/Django_(informatyka)
  2. Strona projektu Django https://www.djangoproject.com/
  3. Co to jest framework? http://pl.wikipedia.org/wiki/Framework
  4. Co nieco o HTTP i żądaniach GET i POST http://pl.wikipedia.org/wiki/Http

Źródła:


Licencja Creative Commons Materiały Python 101 udostępniane przez Centrum Edukacji Obywatelskiej na licencji Creative Commons Uznanie autorstwa-Na tych samych warunkach 4.0 Międzynarodowa.

Utworzony:2017-11-17 o 06:13 w Sphinx 1.5.3
Autorzy:Patrz plik “Autorzy”