Darmowy fragment publikacji:
Tytuł oryginału: Django By Example
Tłumaczenie: Robert Górczyński
ISBN: 978-83-283-2587-6
Copyright © Packt Publishing 2015.
First published in the English language under the title „Django By Example — (9781784391911)”
Polish edition copyright © 2016 by Helion SA. All rights reserved.
All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means,
electronic or mechanical, including photocopying, recording or by any information storage retrieval system,
without permission from the Publisher.
Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej
publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną,
fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje
naruszenie praw autorskich niniejszej publikacji.
Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich
właścicieli.
Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były
kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane
z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie
ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji
zawartych w książce.
Wydawnictwo HELION
ul. Kościuszki 1c, 44-100 GLIWICE
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@helion.pl
WWW: http://helion.pl (księgarnia internetowa, katalog książek)
Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
http://helion.pl/user/opinie/djptas
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.
Printed in Poland.
• Kup książkę
• Poleć książkę
• Oceń książkę
• Księgarnia internetowa
• Lubię to! » Nasza społeczność
Spis tre(cid:258)ci
O autorze
O recenzentach technicznych
Wprowadzenie
Rozdzia(cid:239) 1. Utworzenie aplikacji bloga
Instalacja Django
Utworzenie odizolowanego (cid:258)rodowiska Pythona
Instalacja Django za pomoc(cid:200) pip
Utworzenie pierwszego projektu
Uruchomienie serwera programistycznego
Ustawienia projektu
Projekty i aplikacje
Utworzenie aplikacji
Projekt schematu danych dla bloga
Aktywacja aplikacji
Utworzenie i zastosowanie migracji
Utworzenie witryny administracyjnej dla modeli
Utworzenie superu(cid:285)ytkownika
Witryna administracyjna Django
Dodanie modeli do witryny administracyjnej
Zmiana sposobu wy(cid:258)wietlania modeli
Praca z obiektami QuerySet i mened(cid:285)erami
Tworzenie obiektów
Uaktualnianie obiektów
Pobieranie obiektów
Usuni(cid:218)cie obiektu
Kiedy nast(cid:218)puje okre(cid:258)lenie zawarto(cid:258)ci kolekcji QuerySet?
Utworzenie mened(cid:285)erów modelu
13
14
17
21
22
22
23
24
25
27
28
28
29
31
31
33
33
33
34
36
38
38
39
40
41
41
42
Poleć książkęKup książkę
Spis tre(cid:286)ci
Przygotowanie widoków listy i szczegó(cid:239)ów
Utworzenie widoków listy i szczegó(cid:239)ów
Dodanie wzorców adresów URL do widoków
Kanoniczne adresy URL dla modeli
Utworzenie szablonów dla widoków
Dodanie stronicowania
U(cid:285)ycie widoków opartych na klasach
Podsumowanie
Rozdzia(cid:239) 2. Usprawnienie bloga za pomoc(cid:200) funkcji zaawansowanych
Wspó(cid:239)dzielenie postów przy u(cid:285)yciu wiadomo(cid:258)ci e-mail
Tworzenie formularzy w Django
Obs(cid:239)uga formularzy w widokach
Wysy(cid:239)anie wiadomo(cid:258)ci e-mail w Django
Generowanie formularza w szablonie
Utworzenie systemu komentarzy
Utworzenie formularza na podstawie modelu
Obs(cid:239)uga klasy ModelForm w widoku
Dodanie komentarzy do szablonu szczegó(cid:239)ów posta
Dodanie funkcjonalno(cid:258)ci tagów
Pobieranie podobnych postów
Podsumowanie
Rozdzia(cid:239) 3. Rozbudowa aplikacji bloga
Utworzenie w(cid:239)asnych filtrów i znaczników szablonu
Utworzenie w(cid:239)asnych znaczników szablonu
Utworzenie w(cid:239)asnych filtrów szablonu
Dodanie mapy witryny
Utworzenie kana(cid:239)u wiadomo(cid:258)ci dla postów bloga
Implementacja silnika wyszukiwania z u(cid:285)yciem Solr i Haystack
Instalacja Solr
Utworzenie Solr core
Instalacja Haystack
Utworzenie indeksów
Indeksowanie danych
Utworzenie widoku wyszukiwania
Podsumowanie
Rozdzia(cid:239) 4. Utworzenie witryny spo(cid:239)eczno(cid:258)ciowej
Utworzenie projektu witryny spo(cid:239)eczno(cid:258)ciowej
Rozpocz(cid:218)cie pracy nad aplikacj(cid:200) spo(cid:239)eczno(cid:258)ciow(cid:200)
U(cid:285)ycie frameworka uwierzytelniania w Django
Utworzenie widoku logowania
U(cid:285)ycie widoków uwierzytelniania w Django
Widoki logowania i wylogowania
6
42
43
44
45
46
49
51
52
53
53
54
55
57
59
62
64
65
67
70
75
77
79
79
80
84
87
90
92
92
94
96
97
99
100
103
105
106
106
107
108
113
114
Poleć książkęKup książkę
Spis tre(cid:286)ci
Widoki zmiany has(cid:239)a
Widoki zerowania has(cid:239)a
Rejestracja u(cid:285)ytkownika i profil u(cid:285)ytkownika
Rejestracja u(cid:285)ytkownika
Rozbudowa modelu User
U(cid:285)ycie frameworka komunikatów
Implementacja w(cid:239)asnego mechanizmu uwierzytelniania
Dodanie do witryny uwierzytelnienia za pomoc(cid:200) innej witryny spo(cid:239)eczno(cid:258)ciowej
Uwierzytelnienie za pomoc(cid:200) serwisu Facebook
Uwierzytelnienie za pomoc(cid:200) serwisu Twitter
Uwierzytelnienie za pomoc(cid:200) serwisu Google
Podsumowanie
Rozdzia(cid:239) 5. Udost(cid:218)pnianie tre(cid:258)ci w witrynie internetowej
Utworzenie witryny internetowej do kolekcjonowania obrazów
Utworzenie modelu Image
Zdefiniowanie zwi(cid:200)zku typu „wiele do wielu”
Rejestracja modelu Image w witrynie administracyjnej
Umieszczanie tre(cid:258)ci pochodz(cid:200)cej z innych witryn internetowych
Usuni(cid:218)cie zawarto(cid:258)ci pól formularza
Nadpisanie metody save() egzemplarza ModelForm
Utworzenie bookmarkletu za pomoc(cid:200) jQuery
Utworzenie widoku szczegó(cid:239)owego obrazu
Utworzenie miniatury za pomoc(cid:200) sorl-thumbnail
Dodanie akcji AJAX za pomoc(cid:200) jQuery
Wczytanie jQuery
CSRF w (cid:285)(cid:200)daniach AJAX
Wykonywanie (cid:285)(cid:200)da(cid:241) AJAX za pomoc(cid:200) jQuery
Utworzenie w(cid:239)asnego dekoratora dla widoków
Dodanie stronicowania AJAX do listy widoków
Podsumowanie
Rozdzia(cid:239) 6. (cid:165)ledzenie dzia(cid:239)a(cid:241) u(cid:285)ytkownika
Utworzenie systemu obserwacji
Utworzenie zwi(cid:200)zku typu „wiele do wielu” za pomoc(cid:200) modelu po(cid:258)redniego
Utworzenie widoków listy i szczegó(cid:239)owego dla profilu u(cid:285)ytkownika
Utworzenie widoku AJAX pozwalaj(cid:200)cego na obserwacj(cid:218) u(cid:285)ytkowników
Budowa ogólnego strumienia aktywno(cid:258)ci aplikacji
U(cid:285)ycie frameworka contenttypes
Dodanie ogólnego zwi(cid:200)zku do modelu
Unikni(cid:218)cie powielonych akcji w strumieniu aktywno(cid:258)ci
Dodanie akcji u(cid:285)ytkownika do strumienia aktywno(cid:258)ci
Wy(cid:258)wietlanie strumienia aktywno(cid:258)ci
Optymalizacja kolekcji QuerySet dotycz(cid:200)cej powi(cid:200)zanych obiektów
Tworzenie szablonów dla akcji
119
121
126
126
130
135
137
139
141
143
145
148
149
150
150
152
153
153
154
155
158
165
167
168
170
171
172
175
176
181
183
184
184
187
191
193
194
195
198
199
200
201
202
7
Poleć książkęKup książkę
Spis tre(cid:286)ci
U(cid:285)ycie sygna(cid:239)ów dla denormalizowanych zlicze(cid:241)
Praca z sygna(cid:239)ami
Definiowanie klas konfiguracyjnych aplikacji
U(cid:285)ycie bazy danych Redis do przechowywania ró(cid:285)nych elementów widoków
Instalacja bazy danych Redis
U(cid:285)ycie bazy danych Redis z Pythonem
Przechowywanie ró(cid:285)nych elementów widoków w bazie danych Redis
Przechowywanie rankingu w bazie danych Redis
Kolejne kroki z baz(cid:200) danych Redis
Podsumowanie
Rozdzia(cid:239) 7. Utworzenie sklepu internetowego
Utworzenie projektu sklepu internetowego
Utworzenie modeli katalogu produktów
Rejestracja modeli katalogu w witrynie administracyjnej
Utworzenie widoków katalogu
Utworzenie szablonów katalogu
Utworzenie koszyka na zakupy
U(cid:285)ycie sesji Django
Ustawienia sesji
Wyga(cid:258)ni(cid:218)cie sesji
Przechowywanie koszyka na zakupy w sesji
Utworzenie widoków koszyka na zakupy
Utworzenie procesora kontekstu dla bie(cid:285)(cid:200)cego koszyka na zakupy
Rejestracja zamówienia klienta
Utworzenie modeli zamówienia
Do(cid:239)(cid:200)czenie modeli zamówienia w witrynie administracyjnej
Utworzenie zamówienia klienta
Wykonywanie zada(cid:241) asynchronicznych za pomoc(cid:200) Celery
Instalacja Celery
Instalacja RabbitMQ
Dodanie Celery do projektu
Dodanie zadania asynchronicznego do aplikacji
Monitorowanie Celery
Podsumowanie
Rozdzia(cid:239) 8. Zarz(cid:200)dzanie p(cid:239)atno(cid:258)ciami i zamówieniami
Integracja bramki p(cid:239)atno(cid:258)ci
Utworzenie konta PayPal
Instalacja django-paypal
Dodanie bramki p(cid:239)atno(cid:258)ci
U(cid:285)ycie (cid:258)rodowiska sandbox w PayPal
Otrzymywanie powiadomie(cid:241) o p(cid:239)atno(cid:258)ciach
Konfiguracja aplikacji
Przetestowanie powiadomie(cid:241) o dokonanej p(cid:239)atno(cid:258)ci
8
204
204
207
208
209
210
211
213
215
216
217
218
219
221
222
224
228
228
229
230
231
235
241
244
244
246
247
251
251
251
252
253
255
255
257
258
258
259
260
264
267
269
269
Poleć książkęKup książkę
Spis tre(cid:286)ci
Eksport zamówienia do pliku CSV
Dodanie w(cid:239)asnych akcji do witryny administracyjnej
Rozbudowa witryny administracyjnej za pomoc(cid:200) w(cid:239)asnych widoków
Dynamiczne generowanie rachunków w formacie PDF
Instalacja WeasyPrint
Utworzenie szablonu PDF
Generowanie pliku w formacie PDF
Wysy(cid:239)anie dokumentów PDF za pomoc(cid:200) wiadomo(cid:258)ci e-mail
Podsumowanie
Rozdzia(cid:239) 9. Rozbudowa sklepu internetowego
Utworzenie systemu kuponów
Utworzenie modeli kuponu
Zastosowanie kuponu w koszyku na zakupy
Zastosowanie kuponu w zamówieniu
Internacjonalizacja i lokalizacja projektu
Internacjonalizacja za pomoc(cid:200) Django
Przygotowanie projektu do internacjonalizacji
T(cid:239)umaczenie kodu Pythona
T(cid:239)umaczenie szablonów
U(cid:285)ycie interfejsu do t(cid:239)umacze(cid:241) o nazwie Rosetta
Opcja fuzzy
Wzorce adresów URL dla internacjonalizacji
Umo(cid:285)liwienie u(cid:285)ytkownikowi zmiany j(cid:218)zyka
T(cid:239)umaczenie modeli za pomoc(cid:200) django-parler
Format lokalizacji
U(cid:285)ycie modu(cid:239)u django-localflavor do weryfikacji pól formularza
Utworzenie silnika rekomendacji produktu
Rekomendacja produktu na podstawie wcze(cid:258)niejszych transakcji
Podsumowanie
Rozdzia(cid:239) 10. Budowa platformy e-learningu
Utworzenie platformy e-learningu
Utworzenie modeli kursu
Rejestracja modeli w witrynie administracyjnej
Dostarczenie danych pocz(cid:200)tkowych dla modeli
Utworzenie modeli dla zró(cid:285)nicowanej tre(cid:258)ci
Wykorzystanie dziedziczenia modelu
Utworzenie modeli tre(cid:258)ci
Utworzenie w(cid:239)asnych kolumn modelu
Utworzenie systemu zarz(cid:200)dzania tre(cid:258)ci(cid:200)
Dodanie systemu uwierzytelniania
Utworzenie szablonów uwierzytelniania
Utworzenie widoków opartych na klasach
U(cid:285)ycie domieszek w widokach opartych na klasach
Praca z grupami i uprawnieniami
271
271
274
278
279
279
280
283
284
285
285
286
288
294
296
296
299
300
305
309
312
312
315
316
326
327
328
329
336
337
338
339
341
341
344
345
347
349
354
354
355
357
358
360
9
Poleć książkęKup książkę
Spis tre(cid:286)ci
U(cid:285)ycie zbioru formularzy
Dodanie tre(cid:258)ci do modu(cid:239)ów kursów
Zarz(cid:200)dzanie modu(cid:239)ami i tre(cid:258)ci(cid:200)
Zmiana kolejno(cid:258)ci modu(cid:239)ów i tre(cid:258)ci
Podsumowanie
Rozdzia(cid:239) 11. Buforowanie tre(cid:258)ci
Wy(cid:258)wietlanie kursów
Dodanie rejestracji uczestnika
Utworzenie widoku rejestracji uczestnika
Zapisanie si(cid:218) na kurs
Uzyskanie dost(cid:218)pu do tre(cid:258)ci kursu
Generowanie ró(cid:285)nych rodzajów tre(cid:258)ci
U(cid:285)ycie frameworka buforowania
Dost(cid:218)pne mechanizmy buforowania
Instalacja Memcached
Ustawienia bufora
Dodanie Memcached do projektu
Poziomy buforowania
U(cid:285)ycie dzia(cid:239)aj(cid:200)cego na niskim poziomie API buforowania
Buforowanie fragmentów szablonu
Buforowanie widoków
Podsumowanie
Rozdzia(cid:239) 12. Utworzenie API
Utworzenie API typu RESTful
Instalacja Django Rest Framework
Definiowanie serializacji
Poznajemy analizator sk(cid:239)adni i generatory do okre(cid:258)lonych formatów
Utworzenie widoków listy i szczegó(cid:239)owego
Serializacja zagnie(cid:285)d(cid:285)ona
Utworzenie w(cid:239)asnych widoków
Obs(cid:239)uga uwierzytelnienia
Okre(cid:258)lenie uprawnie(cid:241) do widoków
Utworzenie kolekcji widoku i routerów
Do(cid:239)(cid:200)czenie dodatkowych akcji do kolekcji widoku
Tworzenie w(cid:239)asnych uprawnie(cid:241)
Serializacja tre(cid:258)ci kursu
Podsumowanie
Rozdzia(cid:239) 13. Wdro(cid:285)enie
Wdro(cid:285)enie w (cid:258)rodowisku produkcyjnym
Zarz(cid:200)dzanie ustawieniami dla wielu (cid:258)rodowisk
Instalacja PostgreSQL
Sprawdzenie projektu
Udost(cid:218)pnianie Django za pomoc(cid:200) WSGI
10
367
372
376
380
383
385
385
390
390
393
396
399
401
402
403
403
404
405
405
409
410
412
413
413
414
415
416
417
419
421
422
423
424
425
426
427
429
431
431
431
434
435
436
Poleć książkęKup książkę
Spis tre(cid:286)ci
Instalacja uWSGI
Konfiguracja uWSGI
Instalacja Nginx
(cid:165)rodowisko produkcyjne
Konfiguracja Nginx
Udost(cid:218)pnianie zasobów statycznych i multimedialnych
Ochrona po(cid:239)(cid:200)cze(cid:241) za pomoc(cid:200) SSL
Utworzenie w(cid:239)asnego oprogramowania po(cid:258)rednicz(cid:200)cego
Utworzenie oprogramowania po(cid:258)rednicz(cid:200)cego do obs(cid:239)ugi subdomeny
Obs(cid:239)uga wielu subdomen za pomoc(cid:200) Nginx
Implementacja w(cid:239)asnych polece(cid:241) administracyjnych
Podsumowanie
Skorowidz
436
436
438
439
440
441
442
445
447
448
448
451
452
11
Poleć książkęKup książkęPoleć książkęKup książkę4
Utworzenie witryny
spo(cid:239)eczno(cid:258)ciowej
W poprzednim rozdziale dowiedzia(cid:239)e(cid:258) si(cid:218), jak opracowa(cid:202) map(cid:218) witryny i kana(cid:239) wiadomo(cid:258)ci
dla postów bloga oraz zaimplementowa(cid:202) silnik wyszukiwania w naszej aplikacji bloga. W tym
rozdziale przechodzimy do opracowania aplikacji spo(cid:239)eczno(cid:258)ciowej. Przygotujemy funkcjo-
nalno(cid:258)(cid:202) pozwalaj(cid:200)c(cid:200) u(cid:285)ytkownikom na logowanie, wylogowanie oraz edytowanie i zerowanie
has(cid:239)a. Zobaczysz, jak mo(cid:285)na utworzy(cid:202) niestandardowe profile dla u(cid:285)ytkowników i jak zaim-
plementowa(cid:202) uwierzytelnianie za pomoc(cid:200) innej witryny spo(cid:239)eczno(cid:258)ciowej.
Oto zagadnienia, na których skoncentruj(cid:218) si(cid:218) w tym rozdziale.
(cid:81) U(cid:285)ycie frameworka uwierzytelniania.
(cid:81) Utworzenie widoków pozwalaj(cid:200)cych na rejestracj(cid:218) u(cid:285)ytkowników.
(cid:81) Rozbudowa modelu User o obs(cid:239)ug(cid:218) niestandardowego profilu.
(cid:81) Implementacja uwierzytelnienia spo(cid:239)eczno(cid:258)ciowego za pomoc(cid:200) modu(cid:239)u
python-social-auth.
Prac(cid:218) rozpoczynamy od utworzenia nowego projektu.
Poleć książkęKup książkęDjango. Praktyczne tworzenie aplikacji sieciowych
Utworzenie projektu
witryny spo(cid:239)eczno(cid:258)ciowej
Przyst(cid:218)pujemy teraz do budowy aplikacji spo(cid:239)eczno(cid:258)ciowej umo(cid:285)liwiaj(cid:200)cej u(cid:285)ytkownikom
udost(cid:218)pnianie obrazów znalezionych w internecie. Na potrzeby tego projektu konieczne jest
opracowanie pewnych komponentów. Oto one.
(cid:81) System uwierzytelniania pozwalaj(cid:200)cy u(cid:285)ytkownikowi na rejestrowanie, logowanie,
edycj(cid:218) profilu oraz zmian(cid:218) i zerowanie has(cid:239)a.
(cid:81) System obserwacji pozwalaj(cid:200)cy u(cid:285)ytkownikom na (cid:258)ledzenie swoich poczyna(cid:241).
(cid:81) Funkcjonalno(cid:258)(cid:202) pozwalaj(cid:200)ca na wy(cid:258)wietlanie udost(cid:218)pnianych obrazów oraz
implementacja bookmarkletu umo(cid:285)liwiaj(cid:200)cego u(cid:285)ytkownikowi pobieranie obrazów
z praktycznie ka(cid:285)dej witryny internetowej.
(cid:81) Strumie(cid:241) aktywno(cid:258)ci dla ka(cid:285)dego u(cid:285)ytkownika pozwalaj(cid:200)cy u(cid:285)ytkownikom (cid:258)ledzi(cid:202)
tre(cid:258)(cid:202) dodawan(cid:200) przez obserwowanych u(cid:285)ytkowników.
W tym rozdziale zajmiemy si(cid:218) realizacj(cid:200) pierwszego z wymienionych punktów.
Rozpocz(cid:218)cie pracy nad aplikacj(cid:200) spo(cid:239)eczno(cid:258)ciow(cid:200)
Przejd(cid:283) do pow(cid:239)oki i wydaj poni(cid:285)sze polecenia w celu utworzenia (cid:258)rodowiska wirtualnego dla
projektu, a nast(cid:218)pnie jego aktywacji.
$ mkdir env
$ virtualenv env
$ source env/bin/activate
Znak zach(cid:218)ty w pow(cid:239)oce wy(cid:258)wietla nazw(cid:218) aktywnego (cid:258)rodowiska wirtualnego, co pokaza(cid:239)em
poni(cid:285)ej.
(env)laptop:~ zenx$
W przygotowanym (cid:258)rodowisku wirtualnym zainstaluj framework Django, wydaj(cid:200)c poni(cid:285)sze
polecenie.
$ pip install Django==1.8.6
Kolejnym krokiem jest utworzenie projektu, którego b(cid:218)dziemy u(cid:285)ywa(cid:202) podczas prac nad
aplikacj(cid:200) spo(cid:239)eczno(cid:258)ciow(cid:200). Przejd(cid:283) do pow(cid:239)oki i wydaj poni(cid:285)sze polecenie.
$ django-admin startproject bookmarks
106
Poleć książkęKup książkęRozdzia(cid:225) 4. • Utworzenie witryny spo(cid:225)eczno(cid:286)ciowej
W ten sposób utworzymy nowy projekt Django o nazwie bookmarks wraz z pocz(cid:200)tkow(cid:200) struktur(cid:200)
plików i katalogów. Teraz przejd(cid:283) do nowego katalogu projektu i utwórz now(cid:200) aplikacj(cid:218) o nazwie
account, wydaj(cid:200)c poni(cid:285)sze polecenia.
$ cd bookmarks/
$ django-admin startapp account
Pami(cid:218)taj, aby aktywowa(cid:202) now(cid:200) aplikacj(cid:218) w projekcie poprzez dodanie jej do elementów wy-
mienionych na li(cid:258)cie INSTALLED_APPS w pliku settings.py. Nasz(cid:200) aplikacj(cid:218) umie(cid:258)(cid:202) na pocz(cid:200)tku
listy, przed pozosta(cid:239)ymi zainstalowanymi aplikacjami, tak jak pokaza(cid:239)em poni(cid:285)ej.
INSTALLED_APPS = (
account ,
# …
)
Nie zapomnij o wydaniu poni(cid:285)szego polecenia, aby przeprowadzi(cid:202) synchronizacj(cid:218) bazy danych
z modelami aplikacji domy(cid:258)lnych wskazanymi na li(cid:258)cie INSTALLED_APPS.
$ python manage.py migrate
Teraz mo(cid:285)emy ju(cid:285) przyst(cid:200)pi(cid:202) do budowy systemu uwierzytelniania w projekcie, u(cid:285)ywaj(cid:200)c
frameworka uwierzytelniania.
U(cid:285)ycie frameworka uwierzytelniania
w Django
Django jest dostarczany wraz z wbudowanym frameworkiem uwierzytelniania, który mo(cid:285)e
obs(cid:239)ugiwa(cid:202) uwierzytelnianie u(cid:285)ytkowników, sesje, uprawnienia i grupy u(cid:285)ytkowników. System
uwierzytelniania oferuje widoki dla dzia(cid:239)a(cid:241) najcz(cid:218)(cid:258)ciej podejmowanych przez u(cid:285)ytkowników,
takich jak logowanie, wylogowanie, zmiana has(cid:239)a i zerowanie has(cid:239)a.
Wspomniany framework uwierzytelniania znajduje si(cid:218) w django.contrib.auth i jest u(cid:285)ywany
tak(cid:285)e przez inne pakiety Django, typu contrib. Framework uwierzytelniania wykorzystali(cid:258)my
ju(cid:285) w rozdziale 1. do utworzenia superu(cid:285)ytkownika dla aplikacji bloga, aby mie(cid:202) dost(cid:218)p do
witryny administracyjnej.
Kiedy tworzysz nowy projekt Django za pomoc(cid:200) polecenia startproject, framework uwierzytelniania
zostaje wymieniony w domy(cid:258)lnych ustawieniach projektu. Sk(cid:239)ada si(cid:218) z aplikacji django.contrib.auth
oraz przedstawionych poni(cid:285)ej dwóch klas wymienionych w opcji MIDDLEWARE_CLASSES projektu.
(cid:81) AuthenticationMiddleware. Wi(cid:200)(cid:285)e u(cid:285)ytkowników z (cid:285)(cid:200)daniami za pomoc(cid:200)
mechanizmu sesji.
(cid:81) SessionMiddleware. Zapewnia obs(cid:239)ug(cid:218) bie(cid:285)(cid:200)cej sesji mi(cid:218)dzy poszczególnymi (cid:285)(cid:200)daniami.
107
Poleć książkęKup książkęDjango. Praktyczne tworzenie aplikacji sieciowych
Oprogramowanie po(cid:258)rednicz(cid:200)ce to klasa wraz z metodami wykonywanymi globalnie w trakcie
fazy przetwarzania (cid:285)(cid:200)dania lub udzielania odpowiedzi na nie. W tej ksi(cid:200)(cid:285)ce klasy oprogramo-
wania po(cid:258)rednicz(cid:200)cego b(cid:218)dziemy wykorzystywa(cid:202) w wielu sytuacjach. Temat tworzenia opro-
gramowania po(cid:258)rednicz(cid:200)cego zostanie dok(cid:239)adnie omówiony w rozdziale 13.
Framework uwierzytelniania zawiera równie(cid:285) wymienione poni(cid:285)ej modele.
(cid:81) User. Model u(cid:285)ytkownika wraz z podstawowymi kolumnami, takimi jak username,
password, email, first_name, last_name i is_active.
(cid:81) Group. Model grupy do nadawania kategorii u(cid:285)ytkownikom.
(cid:81) Permission. Uprawnienia pozwalaj(cid:200)ce na wykonywanie okre(cid:258)lonych operacji.
Opisywany framework zawiera tak(cid:285)e domy(cid:258)lne widoki uwierzytelniania i formularze, z których
b(cid:218)dziemy korzysta(cid:202) nieco pó(cid:283)niej.
Utworzenie widoku logowania
Rozpoczynamy od u(cid:285)ycia wbudowanego w Django frameworka uwierzytelniania w celu umo(cid:285)-
liwienia u(cid:285)ytkownikom zalogowania si(cid:218) w witrynie. Aby zalogowa(cid:202) u(cid:285)ytkownika, widok po-
winien wykonywa(cid:202) poni(cid:285)sze akcje.
1. Pobranie nazwy u(cid:285)ytkownika i has(cid:239)a z wys(cid:239)anego formularza.
2. Uwierzytelnienie u(cid:285)ytkownika na podstawie danych przechowywanych w bazie danych.
3. Sprawdzenie, czy konto u(cid:285)ytkownika jest aktywne.
4. Zalogowanie u(cid:285)ytkownika w witrynie i rozpocz(cid:218)cie uwierzytelnionej sekcji.
Najpierw musimy przygotowa(cid:202) formularz logowania. Utwórz nowy plik forms.py w katalogu
aplikacji account i umie(cid:258)(cid:202) w nim poni(cid:285)szy fragment kodu.
from django import forms
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
Formularz b(cid:218)dzie u(cid:285)ywany do uwierzytelnienia u(cid:285)ytkownika na podstawie informacji prze-
chowywanych w bazie danych. Zwró(cid:202) uwag(cid:218) na wykorzystanie wid(cid:285)etu PasswordInput do
wygenerowania elementu HTML input wraz z atrybutem type= password . Przeprowad(cid:283)
edycj(cid:218) pliku views.py aplikacji account i umie(cid:258)(cid:202) w nim poni(cid:285)szy fragment kodu.
from django.http import HttpResponse
from django.shortcuts import render
from django.contrib.auth import authenticate, login
from .forms import LoginForm
def user_login(request):
if request.method == POST :
108
Poleć książkęKup książkęRozdzia(cid:225) 4. • Utworzenie witryny spo(cid:225)eczno(cid:286)ciowej
form = LoginForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(username=cd[ username ],
password=cd[ password ])
if user is not None:
if user.is_active:
login(request, user)
return HttpResponse( Uwierzytelnienie zako(cid:241)czy(cid:239)o si(cid:218) sukcesem. )
else:
return HttpResponse( Konto jest zablokowane. )
else:
return HttpResponse( Nieprawid(cid:239)owe dane uwierzytelniaj(cid:200)ce. )
else:
form = LoginForm()
return render(request, account/login.html , { form : form})
To jest kod podstawowego widoku logowania u(cid:285)ytkownika. Po wywo(cid:239)aniu widoku user_login
przez (cid:285)(cid:200)danie GET za pomoc(cid:200) wywo(cid:239)ania form = LoginForm() tworzymy nowy egzemplarz
formularza logowania i wy(cid:258)wietlamy go w szablonie. Kiedy u(cid:285)ytkownik wy(cid:258)le formularz przy
u(cid:285)yciu (cid:285)(cid:200)dania POST, przeprowadzane s(cid:200) nast(cid:218)puj(cid:200)ce akcje.
1. Utworzenie egzemplarza formularza wraz z wys(cid:239)anymi danymi. Do tego celu s(cid:239)u(cid:285)y
polecenie form = LoginForm(request.POST).
2. Sprawdzenie, czy formularz jest prawid(cid:239)owy. Je(cid:285)eli formularz jest nieprawid(cid:239)owy,
w szablonie wy(cid:258)wietlamy b(cid:239)(cid:218)dy wykryte podczas weryfikacji formularza
(na przyk(cid:239)ad u(cid:285)ytkownik nie wype(cid:239)ni(cid:239) jednego z pól).
3. Je(cid:285)eli wys(cid:239)ane dane s(cid:200) prawid(cid:239)owe, za pomoc(cid:200) metody authenticate()
uwierzytelniamy u(cid:285)ytkownika na podstawie informacji przechowywanych w bazie
danych. Wymieniona metoda pobiera username i password, a zwraca obiekt User,
gdy u(cid:285)ytkownik zostanie uwierzytelniony, lub None w przeciwnym przypadku.
Ponadto je(cid:258)li u(cid:285)ytkownik nie b(cid:218)dzie uwierzytelniony, zwracamy tak(cid:285)e obiekt
HttpResponse wraz z odpowiednim komunikatem.
4. W przypadku pomy(cid:258)lnego uwierzytelnienia u(cid:285)ytkownika za pomoc(cid:200) atrybutu
is_active sprawdzamy, czy jego konto u(cid:285)ytkownika jest aktywne. Wymieniony
atrybut pochodzi z modelu User dostarczanego przez Django. Gdy konto u(cid:285)ytkownika
jest nieaktywne, zwracamy obiekt HttpResponse wraz z odpowiednim komunikatem.
5. Gdy konto u(cid:285)ytkownika jest aktywne, logujemy go w witrynie internetowej.
Rozpoczynamy tak(cid:285)e sesj(cid:218) dla u(cid:285)ytkownika przez wywo(cid:239)anie metody login()
i zwracamy odpowiedni komunikat informuj(cid:200)cy o powodzeniu operacji logowania.
Zwró(cid:202) uwag(cid:218) na ró(cid:285)nice mi(cid:218)dzy metodami authenticate() i login(). Metoda authenticate()
sprawdza dane uwierzytelniaj(cid:200)ce u(cid:285)ytkownika i je(cid:258)li s(cid:200) prawid(cid:239)owe, zwraca obiekt u(cid:285)ytkownika. Natomiast
metoda login() umieszcza u(cid:285)ytkownika w bie(cid:285)(cid:200)cej sesji.
109
Poleć książkęKup książkęDjango. Praktyczne tworzenie aplikacji sieciowych
Teraz musimy opracowa(cid:202) wzorzec adresu URL dla nowo zdefiniowanego widoku. Utwórz
nowy plik urls.py w katalogu aplikacji account i umie(cid:258)(cid:202) w nim poni(cid:285)szy fragment kodu.
from django.conf.urls import url
from . import views
urlpatterns = [
# Widoki logowania.
url(r ^login/$ , views.user_login, name= login ),
]
Przeprowad(cid:283) edycj(cid:218) g(cid:239)ównego pliku urls.py znajduj(cid:200)cego si(cid:218) katalogu projektu bookmarks
i dodaj wzorzec adresu URL aplikacji account, co przedstawi(cid:239)em poni(cid:285)ej.
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r ^admin/ , include(admin.site.urls)),
url(r ^account/ , include( account.urls )),
]
Widok logowania jest teraz dost(cid:218)pny za pomoc(cid:200) adresu URL. Przechodzimy wi(cid:218)c do przygo-
towania szablonu dla tego widoku. Poniewa(cid:285) w projekcie nie mamy jeszcze (cid:285)adnych szablonów,
najpierw musimy utworzy(cid:202) szablon bazowy, który nast(cid:218)pnie b(cid:218)dzie móg(cid:239) by(cid:202) rozszerzony
przez szablon logowania. Wymienion(cid:200) poni(cid:285)ej struktur(cid:218) plików i katalogów utwórz w katalogu
aplikacji account.
templates/
account/
login.html
base.html
Przeprowad(cid:283) edycj(cid:218) pliku base.html i umie(cid:258)(cid:202) w nim poni(cid:285)szy fragment kodu.
{ load staticfiles }
!DOCTYPE html
html
head
title { block title }{ endblock } /title
link href= { static css/base.css } rel= stylesheet
/head
body
div id= header
span class= logo Bookmarks /span
/div
div id= content
{ block content }
{ endblock }
/div
/body
/html
110
Poleć książkęKup książkęRozdzia(cid:225) 4. • Utworzenie witryny spo(cid:225)eczno(cid:286)ciowej
W ten sposób przygotowali(cid:258)my szablon bazowy dla budowanej witryny internetowej. Podob-
nie jak w poprzednim projekcie, tak(cid:285)e w tym style CSS do(cid:239)(cid:200)czamy w szablonie g(cid:239)ównym.
Niezb(cid:218)dne pliki statyczne znajdziesz w materia(cid:239)ach przygotowanych dla ksi(cid:200)(cid:285)ki. Wystarczy
skopiowa(cid:202) podkatalog static z katalogu account we wspomnianych materia(cid:239)ach i umie(cid:258)ci(cid:202) go
w tym samym po(cid:239)o(cid:285)eniu budowanego projektu.
Szablon bazowy definiuje bloki title i content, które mog(cid:200) by(cid:202) wype(cid:239)niane przez tre(cid:258)(cid:202) sza-
blonów rozszerzaj(cid:200)cych szablon bazowy.
Przechodzimy do utworzenia szablonu dla formularza logowania. W tym celu otwórz plik
account/login.html i umie(cid:258)(cid:202) w nim poni(cid:285)szy fragment kodu.
{ extends base.html }
{ block title }Logowanie{ endblock }
{ block content }
h1 Logowanie /h1
p Wype(cid:239)nij poni(cid:285)szy formularz, aby si(cid:218) zalogowa(cid:202): /p
form action= . method= post
{{ form.as_p }}
{ csrf_token }
p input type= submit value= Zaloguj /p
/form
{ endblock }
Ten szablon zawiera formularz, którego egzemplarz jest tworzony w widoku. Poniewa(cid:285) formu-
larz zostanie wys(cid:239)any za pomoc(cid:200) metody POST, do(cid:239)(cid:200)czamy znacznik szablonu { csrf_token }
w celu zapewnienia ochrony przed atakami typu CSRF. Wi(cid:218)cej informacji na temat ataków
CSRF przedstawi(cid:239)em w rozdziale 2.
W bazie danych nie ma jeszcze (cid:285)adnych kont u(cid:285)ytkowników. Konieczne jest utworzenie najpierw
superu(cid:285)ytkownika, aby zapewni(cid:202) sobie dost(cid:218)p do witryny administracyjnej i zarz(cid:200)dza(cid:202) pozosta-
(cid:239)ymi u(cid:285)ytkownikami. Przejd(cid:283) do pow(cid:239)oki i wydaj polecenie python manage.py createsuperuser.
Podaj wybran(cid:200) nazw(cid:218) u(cid:285)ytkownika, adres e-mail i has(cid:239)o. Nast(cid:218)pnie uruchom serwer progra-
mistyczny przez wydanie polecenia python manage.py runserver i w przegl(cid:200)darce internetowej
przejd(cid:283) pod adres http://127.0.0.1:8000/admin/. Dost(cid:218)p do witryny administracyjnej uzyskasz po
podaniu ustalonej przed chwil(cid:200) nazwy u(cid:285)ytkownika i has(cid:239)a. Gdy znajdziesz si(cid:218) ju(cid:285) w witrynie
administracyjnej Django, zobaczysz modele User ((cid:239)(cid:200)cze U(cid:285)ytkownicy) i Group ((cid:239)(cid:200)cze Grupy)
dla wbudowanego w Django frameworka uwierzytelniania. Stron(cid:218) przeznaczon(cid:200) do zarz(cid:200)dzania
u(cid:285)ytkownikami i grupami pokaza(cid:239)em na rysunku 4.1.
Utwórz nowego u(cid:285)ytkownika, u(cid:285)ywaj(cid:200)c do tego witryny administracyjnej, a nast(cid:218)pnie w prze-
gl(cid:200)darce internetowej przejd(cid:283) pod adres http://127.0.0.1:8000/account/login/. Powiniene(cid:258) zo-
baczy(cid:202) wygenerowany szablon wraz z formularzem logowania (patrz rysunek 4.2).
111
Poleć książkęKup książkęDjango. Praktyczne tworzenie aplikacji sieciowych
Rysunek 4.1. Strona przeznaczona do zarz(cid:200)dzania u(cid:285)ytkownikami i grupami
Rysunek 4.2. Szablon wraz z wy(cid:258)wietlonym formularzem logowania
Spróbuj teraz wys(cid:239)a(cid:202) formularz, pozostawiaj(cid:200)c niewype(cid:239)nione jedno z pól. W takim przypadku
formularz jest uznawany za nieprawid(cid:239)owy i zostanie wy(cid:258)wietlony komunikat b(cid:239)(cid:218)du, co poka-
za(cid:239)em na rysunku 4.3.
Rysunek 4.3. Komunikat b(cid:239)(cid:218)du wy(cid:258)wietlany po niewype(cid:239)nieniu wymaganego pola formularza
112
Poleć książkęKup książkęRozdzia(cid:225) 4. • Utworzenie witryny spo(cid:225)eczno(cid:286)ciowej
Je(cid:285)eli podasz dane nieistniej(cid:200)cego u(cid:285)ytkownika lub b(cid:239)(cid:218)dne has(cid:239)o, Django wygeneruje komu-
nikat o nieudanym logowaniu.
Natomiast po podaniu prawid(cid:239)owych danych uwierzytelniaj(cid:200)cych Django wy(cid:258)wietli komunikat
o zako(cid:241)czonym sukcesem logowaniu, co pokaza(cid:239)em na rysunku 4.4.
Rysunek 4.4. Logowanie zako(cid:241)czone powodzeniem
U(cid:285)ycie widoków uwierzytelniania w Django
Framework uwierzytelniania w Django zawiera wiele formularzy i widoków gotowych do na-
tychmiastowego u(cid:285)ycia. Utworzony przed chwil(cid:200) widok logowania to dobre (cid:202)wiczenie poma-
gaj(cid:200)ce w zrozumieniu procesu uwierzytelniania u(cid:285)ytkowników w Django. Jednak w wi(cid:218)kszo(cid:258)ci
przypadków mo(cid:285)esz wykorzysta(cid:202) wspomniane domy(cid:258)lne widoki uwierzytelniania.
Do obs(cid:239)ugi uwierzytelniania Django oferuje wymienione poni(cid:285)ej widoki.
(cid:81) login. Obs(cid:239)uga formularza logowania oraz proces zalogowania u(cid:285)ytkownika.
(cid:81) logout. Obs(cid:239)uga wylogowania u(cid:285)ytkownika.
(cid:81) logout_then_login. Wylogowanie u(cid:285)ytkownika, a nast(cid:218)pnie przeniesienie go
na stron(cid:218) logowania.
Do obs(cid:239)ugi zmiany has(cid:239)a Django oferuje wymienione poni(cid:285)ej widoki.
(cid:81) password_change. Obs(cid:239)uga formularza pozwalaj(cid:200)cego u(cid:285)ytkownikowi na zmian(cid:218) has(cid:239)a.
(cid:81) password_change_done. Strona informuj(cid:200)ca o sukcesie operacji; zostanie
wy(cid:258)wietlona u(cid:285)ytkownikowi, gdy zmiana has(cid:239)a zako(cid:241)czy si(cid:218) powodzeniem.
Natomiast do obs(cid:239)ugi operacji zerowania has(cid:239)a Django oferuje nast(cid:218)puj(cid:200)ce widoki.
(cid:81) password_reset. Umo(cid:285)liwienie u(cid:285)ytkownikowi wyzerowania has(cid:239)a.
Generowane jest przeznaczone tylko do jednokrotnego u(cid:285)ycia (cid:239)(cid:200)cze wraz
z tokenem, które nast(cid:218)pnie b(cid:218)dzie wys(cid:239)ane na adres e-mail danego u(cid:285)ytkownika.
(cid:81) password_reset_done. Wy(cid:258)wietlenie u(cid:285)ytkownikowi strony z informacj(cid:200) o wys(cid:239)aniu
wiadomo(cid:258)ci e-mail wraz z (cid:239)(cid:200)czem pozwalaj(cid:200)cym na wyzerowanie has(cid:239)a.
(cid:81) password_reset_confirm. Widok umo(cid:285)liwiaj(cid:200)cy u(cid:285)ytkownikowi zdefiniowanie
nowego has(cid:239)a.
(cid:81) password_reset_complete. Strona informuj(cid:200)ca o sukcesie operacji; zostanie
wy(cid:258)wietlona u(cid:285)ytkownikowi, gdy wyzerowanie has(cid:239)a zako(cid:241)czy si(cid:218) powodzeniem.
113
Poleć książkęKup książkęDjango. Praktyczne tworzenie aplikacji sieciowych
Zastosowanie wymienionych wy(cid:285)ej widoków mo(cid:285)e zaoszcz(cid:218)dzi(cid:202) spor(cid:200) ilo(cid:258)(cid:202) czasu podczas two-
rzenia witryny internetowej obs(cid:239)uguj(cid:200)cej konta u(cid:285)ytkowników. W widokach tych u(cid:285)ywane s(cid:200)
warto(cid:258)ci domy(cid:258)lne, które oczywi(cid:258)cie mo(cid:285)na nadpisa(cid:202). Przyk(cid:239)adem mo(cid:285)e by(cid:202) wskazanie po(cid:239)o-
(cid:285)enia szablonu przeznaczonego do wygenerowania lub formularza wy(cid:258)wietlanego przez widok.
Wi(cid:218)cej informacji na temat wbudowanych widoków uwierzytelniania znajdziesz na stronie
https://docs.djangoproject.com/en/1.8/topics/auth/default/#module-django.contrib.auth.views.
Widoki logowania i wylogowania
Przeprowad(cid:283) edycj(cid:218) pliku urls.py aplikacji account i dodaj kolejne wzorce adresów URL.
Po wprowadzeniu zmian zawarto(cid:258)(cid:202) wymienionego pliku powinna przedstawia(cid:202) si(cid:218) nast(cid:218)puj(cid:200)co.
from django.conf.urls import url
from . import views
urlpatterns = [
# Poprzedni widok logowania.
# url(r ^login/$ , views.user_login, name= login ),
# Wzorce adresów URL dla widoków logowania i wylogowania.
url(r ^login/$ ,
django.contrib.auth.views.login ,
name= login ),
url(r ^logout/$ ,
django.contrib.auth.views.logout ,
name= logout ),
url(r ^logout-then-login/$ ,
django.contrib.auth.views.logout_then_login ,
name= logout_then_login ),
]
Umie(cid:258)cili(cid:258)my znak komentarza na pocz(cid:200)tku wiersza wzorca adresu URL dla utworzonego
wcze(cid:258)niej widoku user_login. Teraz wykorzystamy widok login oferowany przez wbudowany
w Django framework uwierzytelniania.
Utwórz nowy podkatalog w katalogu szablonów aplikacji account i nadaj mu nazw(cid:218) registration.
Podkatalog ten to domy(cid:258)lna lokalizacja, w której widoki uwierzytelniania Django spodziewaj(cid:200)
si(cid:218) znale(cid:283)(cid:202) szablony. Teraz w nowym podkatalogu utwórz plik login.html i umie(cid:258)(cid:202) w nim po-
ni(cid:285)szy fragment kodu.
{ extends base.html }
{ block title }Logowanie{ endblock }
{ block content }
h1 Logowanie /h1
{ if form.errors }
114
Poleć książkęKup książkęRozdzia(cid:225) 4. • Utworzenie witryny spo(cid:225)eczno(cid:286)ciowej
p
Nazwa u(cid:285)ytkownika lub has(cid:239)o s(cid:200) nieprawid(cid:239)owe.
Spróbuj ponownie.
/p
{ else }
p Wype(cid:239)nij poni(cid:285)szy formularz, aby si(cid:218) zalogowa(cid:202): /p
{ endif }
div class= login-form
form action= { url login } method= post
{{ form.as_p }}
{ csrf_token }
input type= hidden name= next value= {{ next }} /
p input type= submit value= Zaloguj /p
/form
/div
{ endblock }
Ten szablon logowania jest bardzo podobny do utworzonego wcze(cid:258)niej. Domy(cid:258)lnie Django
u(cid:285)ywa formularza AuthenticationForm pochodz(cid:200)cego z django.contrib.auth.forms. Formu-
larz próbuje uwierzytelni(cid:202) u(cid:285)ytkownika i zg(cid:239)asza b(cid:239)(cid:200)d weryfikacji, gdy logowanie zako(cid:241)czy si(cid:218)
niepowodzeniem. W takim przypadku za pomoc(cid:200) znacznika szablonu { if form.errors }
mo(cid:285)na przeanalizowa(cid:202) te b(cid:239)(cid:218)dy, aby sprawdzi(cid:202), czy podane zosta(cid:239)y nieprawid(cid:239)owe dane uwie-
rzytelniaj(cid:200)ce. Zwró(cid:202) uwag(cid:218) na dodanie ukrytego elementu HTML input przeznaczonego do
wys(cid:239)ania warto(cid:258)ci zmiennej o nazwie next. Zmienna jest ustawiania przez widok logowania,
gdy w (cid:285)(cid:200)daniu b(cid:218)dzie przekazany parametr next (na przyk(cid:239)ad http://127.0.0.1:8000/account/
login/?next=/account/).
Warto(cid:258)ci(cid:200) parametru next musi by(cid:202) adres URL. Je(cid:285)eli ten parametr zostanie podany, widok
logowania w Django przekieruje u(cid:285)ytkownika po zalogowaniu do podanego adresu URL.
Teraz utwórz szablon logged_out.html w katalogu registration i umie(cid:258)(cid:202) w nim nast(cid:218)puj(cid:200)cy
fragment kodu.
{ extends base.html }
{ block title }Wylogowanie{ endblock }
{ block content }
h1 Wylogowanie /h1
p Zosta(cid:239)e(cid:258) pomy(cid:258)lnie wylogowany. Mo(cid:285)esz a href= { url
login } zalogowa(cid:202) si(cid:218) ponownie /a . /p
{ endblock }
Ten szablon zostanie przez Django wy(cid:258)wietlony po wylogowaniu u(cid:285)ytkownika.
Po dodaniu wzorców adresu URL oraz szablonów dla widoków logowania i wylogowania bu-
dowana tutaj witryna internetowa jest gotowa na obs(cid:239)ug(cid:218) logowania u(cid:285)ytkowników za pomoc(cid:200)
oferowanych przez Django widoków uwierzytelniania.
115
Poleć książkęKup książkęDjango. Praktyczne tworzenie aplikacji sieciowych
Zwró(cid:202) uwag(cid:218), (cid:285)e widok logout_then_login podany w urlconf nie wymaga u(cid:285)ycia (cid:285)adnego szablonu,
poniewa(cid:285) przekierowuje u(cid:285)ytkownika do widoku logowania.
Przyst(cid:218)pujemy teraz do utworzenia nowego widoku przeznaczonego do wy(cid:258)wietlenia u(cid:285)yt-
kownikowi panelu g(cid:239)ównego (ang. dashboard) po tym, jak ju(cid:285) zaloguje si(cid:218) w aplikacji. Otwórz
plik views.py aplikacji account i umie(cid:258)(cid:202) w nim poni(cid:285)szy fragment kodu.
from django.contrib.auth.decorators import login_required
@login_required
def dashboard(request):
return render(request,
account/dashboard.html ,
{ section : dashboard })
Widok zosta(cid:239) oznaczony dekoratorem login_required frameworka uwierzytelniania. Zadanie
dekoratora login_required polega na sprawdzeniu, czy bie(cid:285)(cid:200)cy u(cid:285)ytkownik zosta(cid:239) uwierzytel-
niony. Je(cid:285)eli u(cid:285)ytkownik jest uwierzytelniony, nast(cid:218)puje wykonanie udekorowanego widoku.
Gdy natomiast u(cid:285)ytkownik nie jest uwierzytelniony, zostaje przekierowany na stron(cid:218) logowa-
nia, a adres URL, do którego próbowa(cid:239) uzyska(cid:202) dost(cid:218)p, b(cid:218)dzie podany jako warto(cid:258)(cid:202) parametru
next (cid:285)(cid:200)dania GET. Tym samym po udanym logowaniu u(cid:285)ytkownik powróci na stron(cid:218), do której
wcze(cid:258)niej próbowa(cid:239) uzyska(cid:202) dost(cid:218)p. Pami(cid:218)taj, (cid:285)e do obs(cid:239)ugi tego rodzaju sytuacji dodali(cid:258)my
w szablonie logowania ukryty element input .
Zdefiniowali(cid:258)my równie(cid:285) zmienn(cid:200) section. Wykorzystamy j(cid:200) do ustalenia, któr(cid:200) sekcj(cid:218) witryny
obserwuje u(cid:285)ytkownik. Wiele widoków mo(cid:285)e odpowiada(cid:202) tej samej sekcji. To jest prosty sposób
na zdefiniowanie, której sekcji odpowiadaj(cid:200) poszczególne widoki.
Teraz nale(cid:285)y utworzy(cid:202) szablon dla widoku panelu g(cid:239)ównego. Utwórz nowy plik w katalogu
templates/account/, nadaj mu nazw(cid:218) dashboard.html i umie(cid:258)(cid:202) w nim przedstawiony poni(cid:285)ej kod.
{ extends base.html }
{ block title }Panel g(cid:239)ówny{ endblock }
{ block content }
h1 Panel g(cid:239)ówny /h1
p Witaj w panelu g(cid:239)ównym. /p
{ endblock }
Kolejnym krokiem jest dodanie poni(cid:285)szego wzorca adresu URL dla nowego widoku. To zadanie
przeprowadzamy w pliku urls.py aplikacji account.
urlpatterns = [
# …
url(r ^$ , views.dashboard, name= dashboard ),
]
116
Poleć książkęKup książkęRozdzia(cid:225) 4. • Utworzenie witryny spo(cid:225)eczno(cid:286)ciowej
Teraz przeprowad(cid:283) edycj(cid:218) pliku settings.py projektu bookmarks i dodaj poni(cid:285)szy fragment kodu.
from django.core.urlresolvers import reverse_lazy
LOGIN_REDIRECT_URL = reverse_lazy( dashboard )
LOGIN_URL = reverse_lazy( login )
LOGOUT_URL = reverse_lazy( logout )
Oto wyja(cid:258)nienie dzia(cid:239)ania poszczególnych opcji.
(cid:81) LOGIN_REDIRECT_URL. Wskazujemy Django adres URL, do którego ma nast(cid:200)pi(cid:202)
przekierowanie, gdy widok contrib.auth.views.login nie otrzymuje
parametru next.
(cid:81) LOGIN_URL. Adres URL, do którego ma nast(cid:200)pi(cid:202) przekierowanie po zalogowaniu
u(cid:285)ytkownika (na przyk(cid:239)ad za pomoc(cid:200) dekoratora login_required).
(cid:81) LOGOUT_URL. Adres URL, do którego ma nast(cid:200)pi(cid:202) przekierowanie po wylogowaniu
u(cid:285)ytkownika.
Do dynamicznego utworzenia adresów URL na podstawie ich nazw u(cid:285)ywamy funkcji
reverse_lazy(). Wymieniona funkcja odwraca adres URL, podobnie jak reverse(), ale mo(cid:285)-
na j(cid:200) wykorzysta(cid:202), gdy zachodzi potrzeba odwrócenia adresu URL przed wczytaniem konfi-
guracji projektu.
Oto krótkie podsumowanie przeprowadzonych dot(cid:200)d dzia(cid:239)a(cid:241).
(cid:81) Do naszego projektu dodali(cid:258)my wbudowane we frameworku uwierzytelniania
Django widoki logowania i wylogowania.
(cid:81) Przygotowali(cid:258)my w(cid:239)asne szablony dla obu widoków i zdefiniowali(cid:258)my prosty
widok, do którego u(cid:285)ytkownik zostanie przekierowany po zalogowaniu.
(cid:81) Na koniec skonfigurowali(cid:258)my ustawienia Django, aby wspomniane adresy URL
by(cid:239)y u(cid:285)ywane domy(cid:258)lnie.
Teraz do szablonu bazowego dodamy (cid:239)(cid:200)cza logowania i wylogowania, co pozwoli na zebranie
wszystkiego w ca(cid:239)o(cid:258)(cid:202).
Konieczne jest ustalenie, czy bie(cid:285)(cid:200)cy u(cid:285)ytkownik jest zalogowany, aby wy(cid:258)wietli(cid:202) prawid(cid:239)owe
(cid:239)(cid:200)cze (logowania lub wylogowania). Bie(cid:285)(cid:200)cy u(cid:285)ytkownik jest przez oprogramowanie po(cid:258)redni-
cz(cid:200)ce ustawiony w obiekcie HttpRequest. Dost(cid:218)p do niego uzyskujesz za pomoc(cid:200) request.user.
U(cid:285)ytkownika znajdziesz w wymienionym obiekcie nawet wtedy, gdy nie zosta(cid:239) uwierzytelniony.
W takim przypadku u(cid:285)ytkownik b(cid:218)dzie zdefiniowany w postaci egzemplarza obiektu AnonymousUser.
Najlepszym sposobem sprawdzenia, czy u(cid:285)ytkownik zosta(cid:239) uwierzytelniony, jest wywo(cid:239)anie
metody request.user.is_authenticated().
Przeprowad(cid:283) edycj(cid:218) pliku base.html i zmodyfikuj element div o identyfikatorze header, tak
jak przedstawi(cid:239)em poni(cid:285)ej.
117
Poleć książkęKup książkęDjango. Praktyczne tworzenie aplikacji sieciowych
div id= header
span class= logo Bookmarks /span
{ if request.user.is_authenticated }
ul class= menu
li { if section == dashboard }class= selected { endif }
a href= { url dashboard } Panel g(cid:239)ówny /a
/li
li { if section == images }class= selected { endif }
a href= # Obrazy /a
/li
li { if section == people }class= selected { endif }
a href= # Osoby /a
/li
/ul
{ endif }
span class= user
{ if request.user.is_authenticated }
Witaj, {{ request.user.first_name }}!
a href= { url logout } Wyloguj /a
{ else }
a href= { url login } Zaloguj /a
{ endif }
/span
/div
Jak mo(cid:285)esz zobaczy(cid:202), menu witryny internetowej b(cid:218)dzie wy(cid:258)wietlane jedynie uwierzytelnio-
nym u(cid:285)ytkownikom. Sprawdzana jest tak(cid:285)e bie(cid:285)(cid:200)ca sekcja witryny, aby doda(cid:202) klas(cid:218) atrybutu
selected do odpowiedniego elementu li i tym samym za pomoc(cid:200) CSS pod(cid:258)wietli(cid:202) nazw(cid:218)
aktualnej sekcji. Wy(cid:258)wietlane jest równie(cid:285) imi(cid:218) uwierzytelnionego u(cid:285)ytkownika i (cid:239)(cid:200)cze pozwa-
laj(cid:200)ce mu na wylogowanie. Je(cid:285)eli u(cid:285)ytkownik nie jest uwierzytelniony, wy(cid:258)wietlone b(cid:218)dzie je-
dynie (cid:239)(cid:200)cze pozwalaj(cid:200)ce mu na zalogowanie.
Teraz w przegl(cid:200)darce internetowej przejd(cid:283) pod adres http://127.0.0.1:8000/account/login/.
Powiniene(cid:258) zobaczy(cid:202) stron(cid:218) logowania. Podaj prawid(cid:239)owe dane uwierzytelniaj(cid:200)ce i kliknij przy-
cisk Zaloguj. Po udanym logowaniu znajdziesz si(cid:218) na stronie pokazanej na rysunku 4.5.
Rysunek 4.5. Strona wy(cid:258)wietlana u(cid:285)ytkownikowi po udanym logowaniu
118
Poleć książkęKup książkęRozdzia(cid:225) 4. • Utworzenie witryny spo(cid:225)eczno(cid:286)ciowej
Jak mo(cid:285)esz zobaczy(cid:202), nazwa sekcji Panel g(cid:239)ówny zosta(cid:239)a za pomoc(cid:200) stylów CSS wy(cid:258)wietlona
innym kolorem czcionki, poniewa(cid:285) odpowiadaj(cid:200)cemu jej elementowi li przypisali(cid:258)my klas(cid:218)
selected. Skoro u(cid:285)ytkownik jest uwierzytelniony, jego imi(cid:218) wy(cid:258)wietlamy po prawej stronie
nag(cid:239)ówka. Kliknij (cid:239)(cid:200)cze Wyloguj, powiniene(cid:258) zobaczy(cid:202) stron(cid:218) pokazan(cid:200) na rysunku 4.6.
Rysunek 4.6. Strona wy(cid:258)wietlana u(cid:285)ytkownikowi po udanym wylogowaniu
Na tej stronie zosta(cid:239) wy(cid:258)wietlony komunikat informuj(cid:200)cy o udanym wylogowaniu i dlatego nie
jest d(cid:239)u(cid:285)ej wy(cid:258)wietlane menu witryny internetowej. (cid:146)(cid:200)cze znajduj(cid:200)ce si(cid:218) po prawej stronie
nag(cid:239)ówka zmienia si(cid:218) na Zaloguj.
Je(cid:285)eli zamiast przygotowanej wcze(cid:258)niej strony wylogowania zostanie wy(cid:258)wietlona strona wy-
logowania witryny administracyjnej Django, sprawd(cid:283) list(cid:218) INSTALLED_APPS projektu i upewnij si(cid:218),
(cid:285)e wpis dotycz(cid:200)cy aplikacji django.contrib.admin znajduje si(cid:218) po account. Oba wymienione
szablony s(cid:200) umieszczone na tej samej wzgl(cid:218)dnej (cid:258)cie(cid:285)ce dost(cid:218)pu i mechanizm wczytywania
szablonów w Django po prostu u(cid:285)yje pierwszego znalezionego.
Widoki zmiany has(cid:239)a
U(cid:285)ytkownikom witryny musimy zapewni(cid:202) mo(cid:285)liwo(cid:258)(cid:202) zmiany has(cid:239)a po zalogowaniu si(cid:218). Zinte-
grujemy wi(cid:218)c oferowane przez framework uwierzytelniania Django widoki przeznaczone do
obs(cid:239)ugi procedury zmiany has(cid:239)a. Otwórz plik urls.py aplikacji account i umie(cid:258)(cid:202) w nim poni(cid:285)sze
wzorce adresów URL.
# Adresy URL przeznaczone do obs(cid:225)ugi zmiany has(cid:225)a.
url(r ^password-change/$ ,
django.contrib.auth.views.password_change ,
name= password_change ),
url(r ^password-change/done/$ ,
django.contrib.auth.views.password_change_done ,
name= password_change_done ),
Widok password_change zapewnia obs(cid:239)ug(cid:218) formularza pozwalaj(cid:200)cego na zmian(cid:218) has(cid:239)a, nato-
miast password_change_done wy(cid:258)wietla komunikat informuj(cid:200)cy o sukcesie po udanej operacji
zmiany has(cid:239)a przez u(cid:285)ytkownika. Przyst(cid:218)pujemy wi(cid:218)c do przygotowania szablonu dla wymie-
nionych widoków.
119
Poleć książkęKup książkęDjango. Praktyczne tworzenie aplikacji sieciowych
Dodaj nowy plik w katalogu templates/registration aplikacji account i nadaj mu nazw(cid:218)
password_change_form.html. Nast(cid:218)pnie w nowym pliku umie(cid:258)(cid:202) poni(cid:285)szy fragment kodu.
{ extends base.html }
{ block title }Zmiana has(cid:239)a{ endblock }
{ block content }
h1 Zmiana has(cid:239)a /h1
p Wype(cid:239)nij poni(cid:285)szy formularz, aby zmieni(cid:202) has(cid:239)o. /p
form action= . method= post
{{ form.as_p }}
p input type= submit value= Zmie(cid:241) /p
{ csrf_token }
/form
{ endblock }
Przedstawiony szablon zawiera formularz przeznaczony do obs(cid:239)ugi procedury zmiany has(cid:239)a.
Teraz w tym samym katalogu utwórz kolejny plik i nadaj mu nazw(cid:218) password_change_done.html.
Nast(cid:218)pnie w nowym pliku umie(cid:258)(cid:202) poni(cid:285)szy fragment kodu.
{ extends base.html }
{ block title }Has(cid:239)o zosta(cid:239)o zmienione{ endblock }
{ block content }
h1 Has(cid:239)o zosta(cid:239)o zmienione /h1
p Zmiana has(cid:239)a zako(cid:241)czy(cid:239)a si(cid:218) powodzeniem. /p
{ endblock }
Ten szablon zawiera jedynie komunikat sukcesu wy(cid:258)wietlany, gdy przeprowadzona przez
u(cid:285)ytkownika operacja zmiany has(cid:239)a zako(cid:241)czy si(cid:218) powodzeniem.
W przegl(cid:200)darce internetowej przejd(cid:283) pod adres http://127.0.0.1:8000/account/password-change/.
Je(cid:285)eli u(cid:285)ytkownik nie jest zalogowany, nast(cid:200)pi przekierowanie na stron(cid:218) logowania. Po
udanym uwierzytelnieniu zobaczysz pokazany na rysunku 4.7 formularz pozwalaj(cid:200)cy na
zmian(cid:218) has(cid:239)a.
W wy(cid:258)wietlonym formularzu nale(cid:285)y poda(cid:202) dotychczasowe has(cid:239)o oraz dwukrotnie nowe, a na-
st(cid:218)pnie klikn(cid:200)(cid:202) przycisk Zmie(cid:241). Je(cid:285)eli operacja przebiegnie bez problemów, zostanie wy-
(cid:258)wietlona strona wraz komunikatem informuj(cid:200)cym o sukcesie (patrz rysunek 4.8).
Wyloguj si(cid:218) i zaloguj ponownie za pomoc(cid:200) nowego has(cid:239)a, aby sprawdzi(cid:202), (cid:285)e wszystko dzia(cid:239)a
zgodnie z oczekiwaniami.
120
Poleć książkęKup książkęRozdzia(cid:225) 4. • Utworzenie witryny spo(cid:225)eczno(cid:286)ciowej
Rysunek 4.7. Formularz pozwalaj(cid:200)cy u(cid:285)ytkownikowi na zmian(cid:218) has(cid:239)a
Rysunek 4.8. Komunikat informuj(cid:200)cy o udanej zmianie has(cid:239)a
Widoki zerowania has(cid:239)a
W pliku urls.py aplikacji account dodaj poni(cid:285)sze wzorce adresów URL dla widoków przezna-
czonych do obs(cid:239)ugi procedury zerowania has(cid:239)a.
# Adresy URL przeznaczone do obs(cid:225)ugi procedury zerowania has(cid:225)a.
url(r ^password-reset/$ ,
django.contrib.auth.views.password_reset ,
name= password_reset ),
url(r ^password-reset/done/$ ,
django.contrib.auth.views.password_reset_done ,
name= password_reset_done ),
121
Poleć książkęKup książkęDjango. Praktyczne tworzenie aplikacji sieciowych
url(r ^password-reset/confirm/(?P uidb64 [-\w]+)/(?P token [-\w]+)/$ ,
django.contrib.auth.views.password_reset_confirm ,
name= password_reset_confirm ),
url(r ^password-reset/complete/$ ,
django.contrib.auth.views.password_reset_complete ,
name= password_reset_complete ),
Dodaj nowy plik w katalogu templates/registration/ aplikacji account i nadaj mu nazw(cid:218)
password_reset_form.html. Nast(cid:218)pnie w utworzonym pliku umie(cid:258)(cid:202) poni(cid:285)szy fragment kodu.
{ extends base.html }
{ block title }Zerowanie has(cid:239)a{ endblock }
{ block content }
h1 Zapomnia(cid:239)e(cid:258) has(cid:239)a? /h1
p Podaj adres e-mail, aby zdefiniowa(cid:202) nowe has(cid:239)o. /p
form action= . method= post
{{ form.as_p }}
p input type= submit value= Wy(cid:258)lij e-mail /p
{ csrf_token }
/form
{ endblock }
Teraz utwórz w tym samym katalogu kolejny plik, tym razem o nazwie password_reset_email.html.
Nast(cid:218)pnie umie(cid:258)(cid:202) w nim poni(cid:285)szy fragment kodu.
Otrzymali(cid:258)my (cid:285)(cid:200)danie wyzerowania has(cid:239)a dla u(cid:285)ytkownika u(cid:285)ywaj(cid:200)cego adresu e-mail {{
(cid:180)email }}. Kliknij poni(cid:285)sze (cid:239)(cid:200)cze:
{{ protocol }}://{{ domain }}{ url password_reset_confirm
uidb64=uid token=token }
Twoja nazwa u(cid:285)ytkownika: {{ user.get_username }}
Szablon ten zostanie u(cid:285)yty do wygenerowania wiadomo(cid:258)ci e-mail wysy(cid:239)anej u(cid:285)ytkownikowi,
który chce przeprowadzi(cid:202) operacj(cid:218) wyzerowania has(cid:239)a.
Utwórz w tym samym katalogu kolejny plik i nadaj mu nazw(cid:218) password_reset_done.html.
Nast(cid:218)pnie umie(cid:258)(cid:202) w nim poni(cid:285)szy fragment kodu.
{ extends base.html }
{ block title }Zerowanie has(cid:239)a{ endblock }
{ block content }
h1 Zerowanie has(cid:239)a /h1
p Wys(cid:239)ali(cid:258)my Ci wiadomo(cid:258)(cid:202) e-mail wraz z instrukcjami pozwalaj(cid:200)cymi na
(cid:180)zdefiniowanie nowego has(cid:239)a. /p
p Je(cid:285)eli nie otrzyma(cid:239)e(cid:258) tej wiadomo(cid:258)ci, to upewnij si(cid:218), (cid:285)e w formularzu zerowania
(cid:180)has(cid:239)a wpisa(cid:239)e(cid:258) adres e-mail podany podczas zak(cid:239)adania konta u(cid:285)ytkownika. /p
{ endblock }
122
Poleć książkęKup książkęRozdzia(cid:225) 4. • Utworzenie witryny spo(cid:225)eczno(cid:286)ciowej
Utwórz kolejny plik szablonu, nadaj mu nazw(cid:218) password_reset_confirm.html, a nast(cid:218)pnie
umie(cid:258)(cid:202) w nim poni(cid:285)szy fragment kodu.
{ extends base.html }
{ block title }Zerowanie has(cid:239)a{ endblock }
{ block content }
h1 Zerowanie has(cid:239)a /h1
{ if validlink }
p Dwukrotnie podaj nowe has(cid:239)o: /p
form action= . method= post
{{ form.as_p }}
{ csrf_token }
p input type= submit value= Zmie(cid:241) has(cid:239)o / /p
/form
{ else }
p (cid:146)(cid:200)cze pozwalaj(cid:200)ce na wyzerowanie has(cid:239)a jest nieprawid(cid:239)owe, poniewa(cid:285)
(cid:180)prawdopodobnie zosta(cid:239)o ju(cid:285) wcze(cid:258)niej u(cid:285)yte. Musisz ponownie rozpocz(cid:200)(cid:202)
(cid:180)procedur(cid:218) zerowania has(cid:239)a. /p
{ endif }
{ endblock }
W kodzie sprawdzamy, czy podane (cid:239)(cid:200)cze jest prawid(cid:239)owe. Oferowany przez Django widok
zerowania has(cid:239)a ustawia zmienn(cid:200) i umieszcza j(cid:200) w kontek(cid:258)cie szablonu. Je(cid:285)eli (cid:239)(cid:200)cze jest pra-
wid(cid:239)owe, wtedy wy(cid:258)wietlamy u(cid:285)ytkownikowi formularz wyzerowania has(cid:239)a.
Utwórz kolejny plik szablonu i nadaj mu nazw(cid:218) password_reset_complete.html. Nast(cid:218)pnie
umie(cid:258)(cid:202) w nim poni(cid:285)szy fragment kodu.
{ extends base.html }
{ block title }Zerowanie has(cid:239)a{ endblock }
{ block content }
h1 Zerowanie has(cid:239)a /h1
p Has(cid:239)o zosta(cid:239)o zdefiniowane. Mo(cid:285)esz si(cid:218) ju(cid:285) a href= { url login
} zalogowa(cid:202) /a . /p
{ endblock }
Na koniec przeprowad(cid:283) edycj(cid:218) szablonu registration/login.html aplikacji account i dodaj po-
ni(cid:285)szy fragment kodu po elemencie form .
p a href= { url password_reset } Zapomnia(cid:239)e(cid:258) has(cid:239)a? /a /p
Teraz w przegl(cid:200)darce internetowej przejd(cid:283) pod adres http://127.0.0.1:8000/account/login/ i kliknij
(cid:239)(cid:200)cze Zapomnia(cid:239)e(cid:258) has(cid:239)a?. Powiniene(cid:258) zobaczy(cid:202) stron(cid:218) pokazan(cid:200) na rysunku 4.9.
123
Poleć książkęKup książkęDjango. Praktyczne tworzenie aplikacji sieciowych
Rysunek 4.9. Strona pozwalaj(cid:200)ca na rozpocz(cid:218)cie procedury wyzerowania has(cid:239)a
Na tym etapie w pliku settings.py projektu trzeba umie(cid:258)ci(cid:202) konfiguracj(cid:218) serwera SMTP, aby
umo(cid:285)liwi(cid:202) Django wysy(cid:239)anie wiadomo(cid:258)ci e-mail. Procedura dodania tego rodzaju konfiguracji
do projektu zosta(cid:239)a omówiona w rozdziale 2. Jednak podczas pracy nad aplikacj(cid:200) mo(cid:285)na skonfi-
gurowa(cid:202) Django do przekazywania wiadomo(cid:258)ci e-mail na standardowe wyj(cid:258)cie zamiast ich
faktycznego wysy(cid:239)ania za pomoc(cid:200) serwera SMTP. Framework Django oferuje mechanizm wy-
(cid:258)wietlania wiadomo(cid:258)ci e-mail w pow(cid:239)oce. Przeprowad(cid:283) edycj(cid:218) pliku settings.py projektu i dodaj
w nim poni(cid:285)szy wiersz kodu.
EMAIL_BACKEND = django.core.mail.backends.console.EmailBackend
Opcja EMAIL_BACKEDN wskazuje na u(cid:285)ycie klasy przeznaczonej do wysy(cid:239)ania wiadomo(cid:258)ci e-mail.
Wró(cid:202) do przegl(cid:200)darki internetowej, podaj adres e-mail istniej(cid:200)cego u(cid:285)ytkownika i kliknij
przycisk Wy(cid:258)lij e-mail. Powiniene(cid:258) zobaczy(cid:202) stron(cid:218) pokazan(cid:200) na rysunku 4.10.
Rysunek 4.10. Komunikat potwierdzaj(cid:200)cy wys(cid:239)anie wiadomo(cid:258)ci e-mail wraz z opisem procedury wyzerowania has(cid:239)a
124
Poleć książkęKup książkęRozdzia(cid:225) 4. • Utworzenie witryny spo(cid:225)eczno(cid:286)ciowej
Spójrz na pow(cid:239)ok(cid:218), w której zosta(cid:239) uruchomiony serwer programistyczny. Powiniene(cid:258) w niej
zobaczy(cid:202) wygenerowan(cid:200) wiadomo(cid:258)(cid:202) e-mail.
IME-Version: 1.0
Content-Type: text/plain; charset= utf-8
Content-Transfer-Encoding: 7bit
Subject: Password reset on 127.0.0.1:8000
From: webmaster@localhost
To: user@domain.com
Date: Thu, 24 Sep 2015 14:35:08 -0000
Message-ID: 20150924143508.62996.55653@zenx.local
Otrzymali(cid:258)my (cid:285)(cid:200)danie wyzerowania has(cid:239)a dla u(cid:285)ytkownika u(cid:285)ywaj(cid:200)cego adresu e-mail
nazwa_u(cid:285)ytkownika@nazwa_domeny.pl. Kliknij poni(cid:285)sze (cid:239)(cid:200)cze:
http://127.0.0.1:8000/account/password-reset/confirm/MQ/45f9c3f30caafd523055fcc/
Twoja nazwa u(cid:285)ytkownika: zenx
Ta wiadomo(cid:258)(cid:202) e-mail jest generowana za pomoc(cid:200) utworzonego wcze(cid:258)niej szablonu password_
(cid:180)reset_email.html. Adres URL pozwalaj(cid:200)cy na przej(cid:258)cie do strony zerowania has(cid:239)a zawiera
token dynamicznie wygenerowany przez Django. Po otworzeniu w przegl(cid:200)darce internetowej
otrzymanego (cid:239)(cid:200)cza przejdziesz na stron(cid:218) pokazan(cid:200) na rysunku 4.11.
Rysunek 4.11. Strona pozwalaj(cid:200)ca na wyzerowanie has(cid:239)a
To jest strona umo(cid:285)liwiaj(cid:200)ca u(cid:285)ytkownikowi podanie nowego has(cid:239)a; odpowiada ona szablonowi
password_reset_confirm.html. W obu polach formularza wpisz nowe has(cid:239)o, a nast(cid:218)pnie kliknij
przycisk Zmie(cid:241) has(cid:239)o. Django utworzy nowe zaszyfrowane has(cid:239)o i zapisze je w bazie danych.
Nast(cid:218)pnie zostanie wy(cid:258)wietlona pokazana na rysunku 4.12 strona wraz z komunikatem infor-
muj(cid:200)cym o sukcesie operacji.
125
Poleć książkęKup książkęDjango. Praktyczne tworzenie aplikacji sieciowych
Rysunek 4.12. Operacja wyzerowania has(cid:239)a zako(cid:241)czy(cid:239)a si(cid:218) powodzeniem
Teraz u(cid:285)ytkownik mo(cid:285)e zalogowa(cid:202) si(cid:218) na swoje konto, podaj(cid:200)c nowe has(cid:239)o. Ka(cid:285)dy token prze-
znaczony do ustawienia nowego has(cid:239)a mo(cid:285)e by(cid:202) u(cid:285)yty tylko jednokrotnie. Je(cid:285)eli ponownie
otworzysz w przegl(cid:200)darce internetowej otrzymane (cid:239)(cid:200)cze, zostanie wy(cid:258)wietlony komunikat
informuj(cid:200)cy o nieprawid(cid:239)owym tokenie.
W ten sposób w projekcie zintegrowa(cid:239)e(cid:258) widoki oferowane przez framework uwierzytelniania
w Django. Wspomniane widoki s(cid:200) odpowiednie do u(cid:285)ycia w wi(cid:218)kszo(cid:258)ci sytuacji. Jednak zawsze
mo(cid:285)esz utworzy(cid:202) w(cid:239)asne widoki, je(cid:258)li potrzebna jest obs(cid:239)uga niestandardowego zachowania.
Rejestracja u(cid:285)ytkownika i profil u(cid:285)ytkownika
Istniej(cid:200)cy u(cid:285)ytkownicy mog(cid:200) si(cid:218) zalogowa(cid:202), wylogowa(cid:202), zmieni(cid:202) has(cid:239)o lub je wyzerowa(cid:202), je(cid:258)li
zapomnieli, jakie by(cid:239)o. Musimy teraz przygotowa(cid:202) widok pozwalaj(cid:200)cy nowym odwiedzaj(cid:200)cym
witryn(cid:218) na za(cid:239)o(cid:285)enie w niej konta u(cid:285)ytkownika.
Rejestracja u(cid:285)ytkownika
Przyst(cid:218)pujemy do utworzenia prostego widoku pozwalaj(cid:200)cego odwiedzaj(cid:200)cemu na zareje-
strowanie si(cid:218) w naszej witrynie internetowej. Zaczniemy od formularza, w którym nowy u(cid:285)yt-
kownik wprowadzi nazw(cid:218) u(cid:285)ytkownika, swoje imi(cid:218) i nazwisko oraz has(cid:239)o. Przeprowad(cid:283) edycj(cid:218)
pliku forms.py w katalogu aplikacji account i umie(cid:258)(cid:202) w nim poni(cid:285)szy fragment kodu.
from django.contrib.auth.models import User
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(label= Has(cid:239)o ,
widget=forms.PasswordInput)
password2 = forms.CharField(label= Powtórz has(cid:239)o ,
widget=forms.PasswordInput)
class Meta:
model = User
fields = ( username , first_name , email )
126
Poleć książkęKup książkęRozdzia(cid:225) 4. • Utworzenie witryny spo(cid:225)eczno(cid:286)ciowej
def clean_password2(self):
cd = self.cleaned_data
if cd[ password ] != cd[ password2 ]:
raise forms.ValidationError( Has(cid:239)a nie s(cid:200) identyczne. )
return cd[ password2 ]
Utworzyli(cid:258)my formularz modelu (klasa ModelForm) dla modelu User. W przygotowanym for-
mularzu b(cid:218)d(cid:200) uwzgl(cid:218)dnione jedynie pola username, first_name i email. Warto(cid:258)ci wymienionych
pól b(cid:218)d(cid:200) weryfikowane na podstawie odpowiadaj(cid:200)cych im kolumn modelu. Je(cid:258)li na przyk(cid:239)ad
u(cid:285)ytkownik wybierze ju(cid:285) istniej(cid:200)c(cid:200) nazw(cid:218) u(cid:285)ytkownika, otrzyma b(cid:239)(cid:200)d w trakcie weryfikacji
formularza. Dodali(cid:258)my dwa dodatkowe pola password i password2 przeznaczone do zdefinio-
wania has(cid:239)a i jego potwierdzenia. Ponadto zdefiniowali(cid:258)my metod(cid:218) clean_password2() odpo-
wiedzialn(cid:200) za porównanie obu wpisanych hase(cid:239). Je(cid:285)eli nie s(cid:200) takie same, formularz b(cid:218)dzie
uznany za nieprawid(cid:239)owy. Ta operacja sprawdzenia nowego has(cid:239)a jest przeprowadzana pod-
czas weryfikacji formularza za pomoc(cid:200) jego metody is_valid(). Istnieje mo(cid:285)liwo(cid:258)(cid:202) dostar-
czenia metody clean_ nazwa_pola () dla dowolnego pola formularza w celu wyczyszczenia
jego warto(cid:258)ci lub zg(cid:239)oszenia b(cid:239)(cid:218)du weryfikacji formularza dla okre(cid:258)lonego pola. Formularze
zawieraj(cid:200) tak(cid:285)e ogóln(cid:200) metod(cid:218) clean() przeznaczon(cid:200) do sprawdzenia ca(cid:239)ego formularza, co
okazuje si(cid:218) u(cid:285)yteczne podczas weryfikacji pól zale(
Pobierz darmowy fragment (pdf)