Django - Widoki

9 stycznia 2017 18:00
Paweł Kucmus

Django

Django to wysoko-poziomowy "Web framework" (nie potrafię tego przetłumaczyć). Framework definiuję strukturę aplikacji i zasady jej działania. Mamy wiele Pythonowych frameworków, a Django jest jednym z bardziej rozbudowanych. Obsługuje żądania i odpowiedzi HTTP, komunikację z bazą danych, cache'owanie, szablonowanie, autentykację i wiele innych. Jest uważane za ociężałe w porównaniu z innymi jednak warto poznać Django (pomijając fakt, że nie musimy używać wszystkiego co oferuje, a tylko elementów nam potrzebnych).

Dla tych, którzy mogą mieć porównanie z innymi, nie tylko Python'owymi framework'ami https://docs.djangoproject.com/en/1.10/intro/overview/.

Wprowadzenie

W Django zastosowano strukturę Model Template View. W porównaniu do MVC programista nie musi "opiekować się" warstwą kontrolera. Upraszczając: żądanie (request) z przeglądarki trafia do widoku - tam decydujemy jakie akcje podjąć, np. jakie akcje na bazie danych wykonać - pracę z bazą ułatwiają modele. Widok zawsze zwraca (return) odpowiedź do przeglądarki. Odpowiedź może zawierać czysty tekst, HTML, PDF, cokolwiek przeglądarka potrafi zaprezentować.

Koniec teorii!

Porządki

Zaczniemy od stworzenia podstawowej struktury projektu. Django udostępnia narzędzie do poprawnego, łatwego i szybkiego przeprowadzenia takiej operacji. Zaczynamy więc od zainstalowania Django.

$ cd /twoj/katalog/roboczy
$ sudo pip install django
$ django-admin startproject pypila
$ cd pypila

Utworzony został projekt w katalogu pypila w Twoim katalogu roboczym. Tam znajduje się podstawowa struktura naszego projektu:

  • Katalog, który lubię nazywać serwisowym o nazwie projektu (pypila), w nim interesują nas dwa moduły:
    • settings.py który gromadzić będzie swoiste ustawienia naszej aplikacji
    • urls.py utrzymujący ścieżki do naszych widoków.
  • Moduł manage.py, który jak sama nazwa wskazuje pozwala zarządzać projektem - jest to jeden z punktów wejścia naszej aplikacji (na tym etapie najważniejszy).


Stworzymy teraz pierwszą aplikację po raz pierwszy posługując się manage.py.

$ python manage.py startapp notes

Moduł notes został utworzony w bazowym katalogu naszego projektu /twoj/katalog/roboczy/pypila/. Do modułu models przenieśmy nasz moduł który rozwijaliśmy na poprzednich zajęciach .

Nasz moduł z wykonanym zadaniem domowym (dla tych którym pies zjadł) można znaleźć tutaj.
Należy przestawić settings.NOTES_FILE.

Widoki

Naszym celem na dziś jest udostępnienie danych z aplikacji, którą stworzyliśmy przez ostatnich kilka tygodni poprzez aplikację webową. Podejdziemy do tematu w konkretny sposób tak aby potem aplikacja mogła być łatwo rozwijana. Naszym zasobem jest notatka. Będą nam potrzebne dwa widoki: pierwszy który będzie zarządzał kolekcją naszych zasobów i drugi, który będzie zarządzał konkretnym zasobem.

Budowa request.

W module notes.views

from django.views.generic import View
from django.http import HttpResponse, Http404

from notes.models import Note, load_initial_data

mamy teraz dostęp do kilku rzeczy z Django, które przydadzą nam się przy pracy jak i do naszego modelu Note i funkcji, która ładuje notatki z bazy (czyli naszego pliku json).


Zadanie 1

Pierwszy widok będzie widokiem do udostępniania kolekcji naszego zasobu.

class NoteListView(View):
def get(self, request): load_initial_data() return HttpResponse(Note.objects.all())

Aby każdy użytkownik widział zawsze "świeże" dane używamy load_initial_data aby załadować nasz zasób.

Następnie modyfikujemy pypila.urls dopisując dwie linie:

from notes import views

urlpatterns = [
    url(r'^note/$', views.NoteListView.as_view()),
    ...
]

Teraz z wiersza poleceń uruchamiamy usługę serwera www dostarczonego przez Django.

$ python manage.py runserver $IP:$PORT

I poprzez przeglądarkę wchodzimy na link podany przez c9.io w popup.

Powinniście zobaczyć brzydką listę swoich notatek (upiększać ją będziemy na przyszłych zajęciach).


Zadanie 2

Teraz zajmiemy się widokiem konkretnej instancji naszego zasobu.

class NoteView(View):
def get_object(self, obj_id): try: return Note.objects.get(id=int(obj_id)) except IndexError: raise Http404
def get(self, request, note_id): load_initial_data() return HttpResponse(self.get_object(note_id))

I dodajemy kolejny wpis do pypila.urls:

urlpatterns = [
    url(r'^note/$', views.NoteListView.as_view()),
    url(r'^note/(?P<note_id>\d+)/$', views.NoteView.as_view()),
    ...
]

W przeglądarce wchodzimy na link http://imie-nazwisko-workspace.c9users.io/note/1/.


Zadanie 3

Dodajmy coś co ułatwia pracę z naszym projektem - filtrowanie notatek wg ich atrybutu board

class NoteListView(View):
def filter_queryset(self, query_set): query_params = self.request.GET if 'board' in query_params: query_set = query_set.filter(board=query_params['board']) return query_set
def get(self, request): load_initial_data() query_set = self.filter_queryset(Note.objects.all()) return HttpResponse(query_set)

Link http://imie-nazwisko-workspace.c9users.io/note/?board=to+do.


Zadanie Domowe

Zabezpieczcie swoje widoki tak aby tylko podając konkretny "query param" jak ?password=tajne_haslo można było zobaczyć listę notatek. Pamiętaj, że zajść musi autentykacja i autoryzacja, a każda z nich w razie niepowodzenia powinna zwracać inną odpowiedź HTTP.

Dodatkowe punkty za użycie nagłówków HTTP zamiast "query param".

Następne zajęcia

Edycja zasobów przy użyciu formularzy.

Comments