Skip to content

Commit

Permalink
Rozwijanie scenariusza Czat (poziom rozszerzony)
Browse files Browse the repository at this point in the history
  • Loading branch information
xinulsw committed Apr 20, 2015
1 parent b66742b commit 29588ab
Show file tree
Hide file tree
Showing 18 changed files with 444 additions and 30 deletions.
Binary file added docs/python/czat/img/czat18index.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/python/czat/img/czat19wiadomosci.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 31 additions & 30 deletions docs/python/czat/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,9 @@ dopisujemy:
from django.core.urlresolvers import reverse_lazy
LOGIN_REDIRECT_URL = reverse_lazy('index')
To wszystko. Przetestuj teraz działanie formularza rejestracji! Spróbuj dodać
To wszystko. Zauważ, że funkcje ``rejestruj()``, ``loguj()`` i ``wyloguj()``,
które umieściliśmy wczesnie w pliku :file:`views.py` nie są już potrzebne!
Przetestuj teraz działanie formularza rejestracji! Spróbuj dodać
zarejestrowanego już użytkownika i wysłać pusty lub niekompletny formularz.


Expand Down Expand Up @@ -624,47 +626,46 @@ Widać powyżej, że treść przesłanej wiadomości odczytujemy ze słownika
``request.POST`` za pomocą metody ``get('tekst', '')``. Jej pierwszy argument
odpowiada nazwie pola formularza użytej w szablonie, które chcemy odczytać.
Drugi argument oznacza wartość domyślną, która zostanie użyta, jeśli
pole będzie niedostępne.

Teraz tworzymy nowy szablon :file:`messages.html` w katalogu :file:`templates/chatter/`.
pole będzie niedostępne. Po sprawdzeniu długości wiadomości, możemy
ją utworzyć wykorzystując konstruktor naszego modelu ``Wiadomosc()``,
któremu w formie nazwanych argumentów podajemy wartości kolejnych pól.
Na koniec zapisujemy nową wiadomość w bazie i przekierowujemy użytkownika
ponownie do widoku ``wiadomsci()``, ale tym razem jest to żądanie typu :term:`GET`.
W odpowiedzi na nie pobieramy wszystkie wiadomości z bazy (``Wiadomosc.objects.all()``),
i przekazujemy do szablonu, który zwracamy użytkownikowi.

Zadaniem szablonu zapisanego w pliku :file:`~/czat/czat/templates/wiadomosci.html`
jest wyświetlenie komunikatów zwrotnych, formularza dodawania wiadomości
i listy wiadomości dodanych.

.. raw:: html

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

.. literalinclude:: messages_z1.html
.. highlight:: html
.. literalinclude:: wiadomosci_z6.html
:linenos:

Uzupełniamy szablon widoku głównego, aby zalogowanym użytkownikom wyświetlał się link prowadzący do strony z wiadomościami. W pliku :file:`index.html` po klauzuli ``{% else %}``, poniżej znacznika ``<h1>`` wstawiamy:

.. raw:: html

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

.. code-block:: html

<p><a href="{% url 'messages' %}">Zobacz wiadomości</a></p>

Na koniec dodajemy nową regułę do :file:`urls.py`:

.. raw:: html

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

.. code-block:: html

url(r'^messages/$', views.messages, name='messages'),
Ćwiczenie 4
=====================

Jeżeli uruchomimy serwer deweloperski, zalogujemy się do aplikacji i odwiedzimy adres *127.0.0.1:8080/messages/*, zobaczymy listę wiadomości dodanych przez użytkowników [#]_.
Powiąż widok ``wiadomosci()`` z adresem */wiadomosci* w pliku :file:`urls.py`,
nadając mu nazwę *wiadomosci*, a nstępnie uzupełnij szablon widoku głównego,
aby zalogowanym użytkownikom wyświetlał się link prowadzący do strony z wiadomościami.
W szablonie ``wiadomosci.html`` dodaj link do strony głównej.

.. [#] Jeżeli w panelu administracyjnym nie dodałeś żadnej wiadomości, lista będzie pusta.
Zaloguj się i przetestuj wyświetlanie[#]_ i dodawanie wiadomości pod adresem
*127.0.0.1:8080/wiadomosci/*. Sprawdź, co się stanie po wysłaniu pustej
wiadomości.

.. figure:: img/messages.png
.. [#] Jeżeli w panelu administracyjnym nie dodałeś żadnej wiadomości,
lista na początku będzie pusta.
JAK TO DZIAŁA: W widoku ``messages()``, podobnie jak w widoku ``login()``, mamy dwie ścieżki postępowania, w zależności od użytej metody HTTP. GET pobiera wszystkie wiadomości (``messages = Message.objects.all()``), przekazuje je do szablonu i renderuje. Django konstruuje odpowiednie zapytanie i mapuje dane z bazy na obiekty klasy ``Message`` (mapowanie obiektowo-relacyjne (ORM)).
Poniższe zrzuty prezentują efekty naszej pracy:

POST zawiera z kolei treść nowej wiadomości, której długość sprawdzamy i jeżeli wszystko jest w porządku, tworzymy nową wiadomość (instancję klasy *Message*, czyli obiekt ``msg``) i zapisujemy ją w bazie danych (wywołujemy metodę obiektu: ``msg.save()``).
.. figure:: img/czat18index.png

.. figure:: img/czat19wiadomosci.png

Materiały
***************
Expand Down
23 changes: 23 additions & 0 deletions docs/python/czat/index_z4.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- czat/czat/templates/czat/index.html -->
<html>
<head></head>
<body>
<h1>Witaj w aplikacji Czat!</h1>

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

{% if user.is_authenticated %}
<p>Jesteś zalogowany jako {{ user.username }}.</p>
<p><a href="{% url 'wyloguj' %}">Wyloguj się</a></p>
{% else %}
<p><a href="{% url 'loguj' %}">Zaloguj się</a></p>
<p><a href="{% url 'rejestruj' %}">Zarejestruj się</a></p>
{% endif %}
</body>
</html>
24 changes: 24 additions & 0 deletions docs/python/czat/index_z6.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!-- czat/czat/templates/czat/index.html -->
<html>
<head></head>
<body>
<h1>Witaj w aplikacji Czat!</h1>

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

{% if user.is_authenticated %}
<p>Jesteś zalogowany jako {{ user.username }}.</p>
<p><a href="{% url 'wiadomosci' %}">Wiadomosci</a></p>
<p><a href="{% url 'wyloguj' %}">Wyloguj się</a></p>
{% else %}
<p><a href="{% url 'loguj' %}">Zaloguj się</a></p>
<p><a href="{% url 'rejestruj' %}">Zarejestruj się</a></p>
{% endif %}
</body>
</html>
Empty file added python/czat/czat/__init__.py
Empty file.
9 changes: 9 additions & 0 deletions python/czat/czat/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-

# czat/czat/admin.py

from django.contrib import admin
from czat.models import Wiadomosc # importujemy nasz model

# rejestrujemy model Wiadomosc w panelu administracyjnym
admin.site.register(Wiadomosc)
19 changes: 19 additions & 0 deletions python/czat/czat/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# czat/czat/models.py

from django.db import models
from django.contrib.auth.models import User

class Wiadomosc(models.Model):
"""Klasa reprezentująca wiadomość w systemie"""
tekst = models.CharField(u'wiadomość', max_length=250)
data_pub = models.DateTimeField(u'data publikacji')
autor = models.ForeignKey(User)

class Meta: # ustawienia dodatkowe
verbose_name = u'wiadomość' # nazwa obiektu w języku polskim
verbose_name_plural = u'wiadomości' # nazwa obiektów w l.m.
ordering = ['data_pub'] # domyślne porządkowanie danych

def __unicode__(self):
return self.tekst # "autoprezentacja"
88 changes: 88 additions & 0 deletions python/czat/czat/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# -*- coding: utf-8 -*-

"""
Django settings for czat project.
For more information on this file, see
https://docs.djangoproject.com/en/1.6/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.6/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'd3qrzpt#6s&8s6p@i^s^vtfd^pbltt51dfu!x@@116&@kqbq$!'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

TEMPLATE_DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'czat', #rejestrujemy aplikację czat w projekcie
)

MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'czat.urls'

WSGI_APPLICATION = 'czat.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}

# Internationalization
# https://docs.djangoproject.com/en/1.6/topics/i18n/

LANGUAGE_CODE = 'pl'

TIME_ZONE = 'Europe/Warsaw'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.6/howto/static-files/

STATIC_URL = '/static/'

from django.core.urlresolvers import reverse_lazy
LOGIN_REDIRECT_URL = reverse_lazy('index')
24 changes: 24 additions & 0 deletions python/czat/czat/templates/czat/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!-- czat/czat/templates/czat/index.html -->
<html>
<head></head>
<body>
<h1>Witaj w aplikacji Czat!</h1>

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

{% if user.is_authenticated %}
<p>Jesteś zalogowany jako {{ user.username }}.</p>
<p><a href="{% url 'wiadomosci' %}">Wiadomosci</a></p>
<p><a href="{% url 'wyloguj' %}">Wyloguj się</a></p>
{% else %}
<p><a href="{% url 'loguj' %}">Zaloguj się</a></p>
<p><a href="{% url 'rejestruj' %}">Zarejestruj się</a></p>
{% endif %}
</body>
</html>
15 changes: 15 additions & 0 deletions python/czat/czat/templates/czat/loguj.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<html>
<body>
<h1>Logowanie użytkownika</h1>
{% if user.is_authenticated %}
<p>Jesteś już zalogowany jako {{ user.username }}.
<br /><a href="/">Strona główna</a></p>
{% else %}
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Zaloguj</button>
</form>
{% endif %}
</body>
</html>
15 changes: 15 additions & 0 deletions python/czat/czat/templates/czat/rejestruj.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<html>
<body>
<h1>Rejestracja użytkownika</h1>
{% if user.is_authenticated %}
<p>Jesteś już zarejestrowany jako {{ user.username }}.
<br /><a href="/">Strona główna</a></p>
{% else %}
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Zarejestruj</button>
</form>
{% endif %}
</body>
</html>
33 changes: 33 additions & 0 deletions python/czat/czat/templates/czat/wiadomosci.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!-- czat/czat/templates/czat/wiadomosci.html -->
<html>
<body>
<h1>Wiadomości</h1>

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

<h2>Dodaj wiadomość</h2>
<form method="POST">
{% csrf_token %}
<input type="text" name="tekst" />
<button type="submit">Zapisz</button>
</form>

<h2>Lista wiadomości:</h2>
<ol>
{% for wiadomosc in wiadomosci %}
<li>
<strong>{{ wiadomosc.autor.username }}</strong> ({{ wiadomosc.data_pub }}):
<br /> {{ wiadomosc.tekst }}
</li>
{% endfor %}
</ol>

<p><a href="{% url 'index' %}">Strona główna</a></p>
</body>
</html>
37 changes: 37 additions & 0 deletions python/czat/czat/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# czat/czat/urls.py

from django.conf.urls import patterns, include, url
from django.contrib import admin
from czat import views # importujemy zdefiniowane w pliku views.py widoki

admin.autodiscover() # potrzebne tylko w Django 1.6

from django.views.generic.edit import CreateView
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.core.urlresolvers import reverse_lazy

urlpatterns = patterns('',
# Examples:
# url(r'^$', 'czat.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),

# główny adres (/) o nazwie index łączymy z widokiem index
url(r'^$', views.index, name='index'),
#url(r'^rejestruj/', views.rejestruj, name='rejestruj'),
#url(r'^loguj/', views.loguj, name='loguj'),
#url(r'^wyloguj/', views.wyloguj, name='wyloguj'),
url(r'^rejestruj/', CreateView.as_view(
template_name='czat/rejestruj.html',
form_class=UserCreationForm,
success_url='/'), name='rejestruj'),
url(r'^loguj/', 'django.contrib.auth.views.login',
{'template_name': 'czat/loguj.html'},
name='loguj'),
url(r'^wyloguj/', 'django.contrib.auth.views.logout',
{'next_page': reverse_lazy('index')},
name='wyloguj'),
url(r'^wiadomosci/', views.wiadomosci, name='wiadomosci'),

url(r'^admin/', include(admin.site.urls)),
)

0 comments on commit 29588ab

Please sign in to comment.