• Nie Znaleziono Wyników

Django, cz. 2

N/A
N/A
Protected

Academic year: 2021

Share "Django, cz. 2"

Copied!
48
0
0

Pełen tekst

(1)

Środowisko Django, cz. 2

Marcin Młotkowski

(2)

Plan wykładu

1 Formularze

Trochę teorii

Obsługa żądań GET Obiekty formularzowe 2 Różne Zarządzanie sesjami Polonizacja 3 Testowanie Testy jednostkowe

(3)

Plan wykładu

1 Formularze

Trochę teorii

Obsługa żądań GET Obiekty formularzowe 2 Różne Zarządzanie sesjami Polonizacja 3 Testowanie Testy jednostkowe Symulowanie klienta

(4)

Formularze

Różne Testowanie

Trochę teorii Obsługa żądań GET Obiekty formularzowe

Podstawowe żądania HTTP

GET

GET <ścieżka do pliku> HTTP 1.1

GET <ścieżka>?query=python&subquery=django HTTP 1.1

POST /login HTTP 1.1 login=admin

(5)

Podstawowe żądania HTTP

GET

GET <ścieżka do pliku> HTTP 1.1

GET <ścieżka>?query=python&subquery=django HTTP 1.1 POST

POST /login HTTP 1.1 login=admin

(6)

Inne typy żądań

HEAD PUT DELETE TRACE CONNECT OPTIONS

(7)

Formularze

Różne Testowanie

Trochę teorii Obsługa żądań GET Obiekty formularzowe

Analiza żądań

Przypomnienie: widoki

defhello(request): ...

path, get full path() (z zapytaniem) method: może być GET bądź POST GET, POST: podobne do słowników

(8)

Analiza żądań

Przypomnienie: widoki

defhello(request): ...

Obiekt Request, atrybuty

path, get full path() (z zapytaniem) method: może być GET bądź POST GET, POST: podobne do słowników

(9)

Kiedy GET, kiedy POST

GET

Wyświetlenie danych, bez ich zmiany (np. wyszukiwanie). POST

(10)

Składnia

<form action="/search/" method="get"> <input type="text" name="query"> <input type="submit" value="Szukaj"> </form>

Widok: urls.py

urlpatterns = patterns(””, # ...

(11)

fromdjango.httpimportHttpResponse

fromdjango.shortcutsimportrender to response

frommysite.zapisy.models importWyklad

defsearch form(request):

returnrender to response(’search form.html’)

defsearch(request):

if ’query’ inrequest.GET and request.GET[’query’]:

query = request.GET[”query”]

wyklady = Wyklad.objects.filter(tytul icontains=query)

returnrender to response(’search results.html’, {’wyklady’: wyklady, ’query’: query})

else

returnrender to response(’search form.html’, {’error’: True})

(12)

szablon search form.html

{% if error %}

<p style="color: red;">Proszę zadać pytanie</p> {% endif %}

<form action="/search/" method="get"> <input type="text" name="query"> <input type="submit" value="Szukaj"> </form>

(13)

Obiekty formularzowe: co to takiego

obiekty, z których można łatwo wyprodukować formularze można konfigurować różne parametry (rozmiar pola, opcjonalność pól);

(14)

Obiekty formularzowe

fromdjangoimportforms

classContactForm(forms.Form):

subject = forms.CharField(max length=100) email = forms.EmailField(required=False,

label=”Podaj email”)

(15)

Sposoby walidacji podawanych danych

classContactForm(forms.Form): ...

defclean email(self):

em = self.cleaned data[’email’]

ifem niepoprawny :

raiseforms.ValidationError(’Niepoprawny email!’)

(16)

Użycie obiektu formularza

Metody i pola obiektu

.as table: do włożenia do tabeli .as ul: do włożenia do wyliczenia <ul> .as p: wkłada w znaczniki <p>

(17)

Osadzenie formularza w szablonie

Przykład użycia

{% if form.errors %} <p style="color: red;">

Popraw błędy {{ form.errors|pluralize }}. </p>

{% endif %}

<form action="" method="post"> <table>

{{ form.as_table }} </table>

<input type="submit" value="Submit"> </form>

(18)

Wiązanie widoku z formularzem

fromdjango.shortcutsimportrender to response

frommysite.contact.forms importContactForm

defcontact(request):

if request.method == ’POST’:

form = ContactForm(request.POST)

ifform.is valid():

cd = form.cleaned data

operacja(cd[’subject’], cd[’message’],

cd.get(’e-mail’,’noreply@example.com’))

(19)

Inicjowanie wartościami początkowymi

form = ContactForm(initial=

(20)

Plan wykładu

1 Formularze Trochę teorii

Obsługa żądań GET Obiekty formularzowe 2 Różne Zarządzanie sesjami Polonizacja 3 Testowanie Testy jednostkowe

(21)

Sesje

Sesja: ciąg akcji związanych z jednym użytkownikiem; na przykład zakupy w sklepie internetowym.

Realizacja Ciasteczka

(22)

Obsługa sesji w Django

Co potrzebujemy:

w MIDDLEWARE CLASSES ma być

’django.contrib.sessions.middleware.SessionMiddleware’.

(23)

Jak używać sesji

Atrybut request.session

(24)

Formularze Różne Testowanie Zarządzanie sesjami Polonizacja

Przykład

Logowanie deflogin(request): ifrequest.method !=’POST’:

raiseHttp404(’Tylko POSTs są dopuszczalne’) try:

m = User.objects.get(username=request.POST[’username’]) if m.password == request.POST[’password’]:

request.session[’user id’] = m.id

returnHttpResponseRedirect(’/you-are-logged-in/’) exceptUser.DoesNotExist:

returnHttpResponse(”Nieudane logowanie :-(”)

(25)

Przykład

Logowanie

deflogin(request):

ifrequest.method !=’POST’:

raiseHttp404(’Tylko POSTs są dopuszczalne’) try:

m = User.objects.get(username=request.POST[’username’]) if m.password == request.POST[’password’]:

request.session[’user id’] = m.id

returnHttpResponseRedirect(’/you-are-logged-in/’) exceptUser.DoesNotExist:

returnHttpResponse(”Nieudane logowanie :-(”)

request.session[’user id’] służy do identyfikacji, czy użytkownik jest zalogowany.

(26)

Wylogowanie

deflogout(request):

try:

delrequest.session[’user id’]

exceptKeyError:

pass

(27)

Formularze Różne Testowanie Zarządzanie sesjami Polonizacja

Podstawowe pojęcia

Internacjonalizacja (I18N)

Przygotowanie programu do tworzenia różnych wersji językowych.

(28)

Podstawowe pojęcia

Internacjonalizacja (I18N)

Przygotowanie programu do tworzenia różnych wersji językowych. Lokalizacja

(29)

Włączanie/wyłączanie internacjonalizacji

USE I18N = True

TEMPLATE CONTEXT PROCESSORS = ( ’django.core.context processors.i18n’

(30)

Tłumaczenie napisów w widokach

fromdjango.utils.translation importugettext as

defwidoczek(request):

output = (”Welcome to my site.”)

(31)

Tłumaczenia w szablonach

Tłumaczenie pojedynczego napisu

<title>{% trans "This is the title." %}</title> Tłumaczenie większych fragmentów

{% blocktrans %}

This string will have {{ value }} inside. {% endblocktrans %}

(32)

Formularze Różne Testowanie Zarządzanie sesjami Polonizacja

Tłumaczenie

django-admin.py makemessages -l pl

tworzy plik locale/pl/LC MESSAGES/django.po. String z pliku źródłowego jest kluczem, my powinniśmy uzupełnić o tłumaczenie

(33)

Tłumaczenie

django-admin.py makemessages -l pl

tworzy plik locale/pl/LC MESSAGES/django.po. String z pliku źródłowego jest kluczem, my powinniśmy uzupełnić o tłumaczenie Po wpisaniu tłumaczeń

(34)

Plan wykładu

1 Formularze Trochę teorii

Obsługa żądań GET Obiekty formularzowe 2 Różne Zarządzanie sesjami Polonizacja 3 Testowanie Testy jednostkowe

(35)

Formularze Różne Testowanie Testy jednostkowe Symulowanie klienta

Poziomy testowania

Testy jednostkowe

Patrz: wykład 9: unittest

(36)

Poziomy testowania

Testy jednostkowe

Patrz: wykład 9: unittest Testy klienckie

(37)

Mała sugestia

Zamiast

importunittest lepiej

(38)

Różnice między unittest a django.test

automatyczne ładowanie danych testowych do bazy testowej; Każdy test jest odrębną transakcją;

dodatkowe asercje do testowania HTML’a, przekierowań HTTP, etc.

(39)

Formularze Różne Testowanie Testy jednostkowe Symulowanie klienta

Przykład

fromdjango.test importTestCase

fromwyklad.zapisy.models importWyklad

classWykladTestCase(TestCase):

defsetUp(self):

Wyklad.objects.create(nazwa=’Python’, ects=3)

deftest zapisu(self):

py = Wyklad.objects.get(nazwa=’Python’)

self.assertEqual(py.ects, 3)

Wyszukuje wszystkie pliki test*.py i traktuje je jako elementy zestawu testów.

(40)

Przykład

fromdjango.test importTestCase

fromwyklad.zapisy.models importWyklad

classWykladTestCase(TestCase):

defsetUp(self):

Wyklad.objects.create(nazwa=’Python’, ects=3)

deftest zapisu(self):

py = Wyklad.objects.get(nazwa=’Python’)

(41)

Testowa baza danych

Testowa baza danych (test baza produkcyjna ) jest czyszczona po każdym teście.

(42)

Dane testowe

Dane testowe z istniejącej bazy danych: manage.py syncdb

tworzy plik initial data z danymi

(43)

Inne dane testowe

fromdjango.test importTestCase

fromwyklad.zapisy.models importWyklad

classWykladTestCase(TestCase): fixtures = [’jesien.json’,’wiosna’] ...

(44)

Formularze Różne Testowanie Testy jednostkowe Symulowanie klienta

Klient testowy

django.test.client.Client

(45)

Klient testowy

django.test.client.Client

Symuluje wysyłanie zapytań GET/POST. Można też używać narzędzi typu Selenium.

(46)

Przykład scenariusza

fromdjango.test.clientimportClient

student = Client()

response = student.post(’/login/’,

{’username’: ’i123456’,’password’: ’123456’})

printresponse.status code # 200

response = student.get(’/student/profil/’)

(47)

Formularze Różne Testowanie Testy jednostkowe Symulowanie klienta

Uwagi

Scenariusze można opakować w przypadki testowe i korzystać z dodatkowych asercji z django.test.TestCase

(48)

Uwagi

Scenariusze można opakować w przypadki testowe i korzystać z dodatkowych asercji z django.test.TestCase

django dostarcza specjalizowanych klas do implementacji różnych testów wraz z sugestiami w jakich sytuacjach ich używać.

Cytaty

Powiązane dokumenty