Widoki w Pytigonie to warstwa orkiestracji — pobierają parametry URL, dobierają dane z modeli, nakładają logikę biznesową i przekazują wszystko szablonom do renderowania. Ogólne widoki Pytigona obsługują 90% typowych wzorców, z hakami na pozostałe 10%.
Klasy widoków Pytigona rozszerzają oparte na klasach widoki Django o funkcjonalność nastawioną na tabele:
django.views.generic.View
→ django.views.generic.base.TemplateView
→ pytigon_lib.schviews.views.BaseView
→ pytigon_lib.schviews.views.TableView
→ pytigon_lib.schviews.views.FormView
→ pytigon_lib.schviews.views.EditView
→ pytigon_lib.schviews.views.AddView
→ pytigon_lib.schviews.views.TreeView
→ pytigon_lib.schviews.views.ActionView
TableView obsługuje widoki listy — pobiera rekordy, nakłada filtry, zarządza paginacją i wspiera niestandardowe akcje.
class MyTableView(TableView):
model = MyModel
template_name = "myapp/mymodel_list.html"
columns = ['name', 'status', 'created']
sort = 'name'
order = 'asc'
page_size = 25
search_fields = ['name', 'description']
def get_queryset(self):
qs = super().get_queryset()
if hasattr(self.model, 'filter_by_permissions'):
qs = self.model.filter_by_permissions(qs, self.request)
return qs
Widok automatycznie przetwarza te parametry GET:
| Parametr | Przeznaczenie |
|---|---|
offset |
Przesunięcie paginacji |
sort |
Nazwa pola sortowania |
order |
Kierunek sortowania (asc/desc) |
search |
Tekst wyszukiwania |
Żądania POST do widoku listy mogą nieść akcje tabeli (zaznacz wiersze → wykonaj operację wsadową). Obsługuje je metoda klasowa table_action modelu:
@classmethod
def table_action(cls, list_view, request, data):
if data.get("action") == "export":
# Obsłuż eksport
return actions.refresh(request)
return standard_table_action(cls, list_view, request, data, ["copy", "paste"])
Te widoki obsługują operacje na pojedynczym rekordzie:
class AlbumEditView(EditView):
model = Album
def get_form_class(self):
if self.object and hasattr(self.object, 'get_form_class'):
return self.object.get_form_class(self, self.request, False)
return super().get_form_class()
def form_valid(self, form):
if hasattr(self.object, 'post_form'):
if not self.object.post_form(self, form, self.request):
return self.form_invalid(form)
return super().form_valid(form)
add_paramWidok dodawania przyjmuje dynamiczny parametr przez URL, dostępny potem jako view.kwargs['add_param']. Umożliwia to tworzenie nowych rekordów zależne od kontekstu — na przykład utworzenie rekordu podrzędnego z uprzednio wybranym rodzicem.
Niestandardowe akcje, które nie pasują do wzorców CRUD:
class GenerateReportView(ActionView):
def post(self, request, *args, **kwargs):
# Przetwórz akcję
report_data = generate_report(request.POST)
return JsonResponse(report_data)
Każdy widok wzbogaca kontekst szablonu o te zmienne:
form_edit — True przy renderowaniu formularza edycji
form_add — True przy renderowaniu formularza dodawania
form_delete — True przy renderowaniu formularza usuwania
form_list — True przy renderowaniu listy
form_info — True przy renderowaniu widoku informacji
form_grid — True przy renderowaniu widoku siatki
show_form — True przy renderowaniu dowolnego formularza (edycja, dodawanie, usuwanie, info)
readonly — True, gdy URL zawiera "/_"
ro — "_" jeśli tylko do odczytu, w przeciwnym razie ""
default_template — Szablon bazowy dla tego widoku
default_template2 — Alternatywny szablon bazowy
Widoki integrują się z systemem uprawnień Django. Zdefiniuj uprawnienia dla poszczególnych akcji:
class AlbumView(TableView):
permission_add = "tables_demo.add_album"
permission_edit = "tables_demo.change_album"
permission_delete = "tables_demo.delete_album"
Pytigon sprawdza je automatycznie przed przetworzeniem żądań.