Views in Pytigon are the orchestration layer — they take URL parameters, fetch data from models, apply business logic, and hand everything to templates for rendering. Pytigon's generic views handle 90% of common patterns, with hooks for the remaining 10%.
Pytigon's view classes extend Django's class-based views with table-centric functionality:
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 handles list views — fetching records, applying filters, managing pagination, and supporting custom actions.
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
The view automatically processes these GET parameters:
| Parameter | Purpose |
|---|---|
offset |
Pagination offset |
sort |
Sort field name |
order |
Sort direction (asc/desc) |
search |
Search text |
POST requests to the list view can carry table actions (select rows → perform batch operation). The table_action class method on the model handles these:
@classmethod
def table_action(cls, list_view, request, data):
if data.get("action") == "export":
# Handle export
return actions.refresh(request)
return standard_table_action(cls, list_view, request, data, ["copy", "paste"])
These views handle single-record operations:
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_param ParameterThe add view accepts a dynamic parameter via the URL that becomes available as view.kwargs['add_param']. This enables context-dependent new record creation — for example, creating a child record with the parent pre-selected.
Custom actions that don't fit CRUD patterns:
class GenerateReportView(ActionView):
def post(self, request, *args, **kwargs):
# Process the action
report_data = generate_report(request.POST)
return JsonResponse(report_data)
Every view enriches the template context with these variables:
form_edit — True when rendering an edit form
form_add — True when rendering an add form
form_delete — True when rendering a delete form
form_list — True when rendering a list
form_info — True when rendering info view
form_grid — True when rendering grid view
show_form — True when rendering any form (edit, add, delete, info)
readonly — True when URL contains "/_"
ro — "_" if readonly, "" otherwise
default_template — Base template for this view
default_template2 — Alternative base template
Views integrate with Django's permission system. Define permissions per action:
class AlbumView(TableView):
permission_add = "tables_demo.add_album"
permission_edit = "tables_demo.change_album"
permission_delete = "tables_demo.delete_album"
Pytigon checks these automatically before processing requests.