diff --git a/src/c3nav/control/templates/control/fragment_pagination.html b/src/c3nav/control/templates/control/fragment_pagination.html
index c27058cb..85196c56 100644
--- a/src/c3nav/control/templates/control/fragment_pagination.html
+++ b/src/c3nav/control/templates/control/fragment_pagination.html
@@ -1,21 +1,21 @@
{% load i18n %}
- {% if objects.has_previous %}
+ {% if page_obj.has_previous %}
« {% trans 'first' %}
·
-
+
‹ {% trans 'previous' %}
·
{% endif %}
- {% with page_number=objects.number num_pages=objects.paginator.num_pages %}
+ {% with page_number=page_obj.number num_pages=paginator.num_pages %}
{% blocktrans %}Page {{ page_number }} of {{ num_pages }}{% endblocktrans %}
{% endwith %}
- {% if objects.has_next %}
- ·
+ {% if page_obj.has_next %}
+ ·
{% trans 'next' %} ›
- ·
+ ·
{% trans 'last' %} »
{% endif %}
diff --git a/src/c3nav/control/templates/control/mesh_nodes.html b/src/c3nav/control/templates/control/mesh_nodes.html
index 5fd7bb63..119ca019 100644
--- a/src/c3nav/control/templates/control/mesh_nodes.html
+++ b/src/c3nav/control/templates/control/mesh_nodes.html
@@ -4,8 +4,6 @@
{% block heading %}{% trans 'Mesh' %}{% endblock %}
{% block subcontent %}
- {% include 'control/fragment_pagination.html' with objects=nodes %}
-
{% trans 'Address' %} |
@@ -24,6 +22,4 @@
{% endfor %}
-
- {% include 'control/fragment_pagination.html' with objects=nodes %}
{% endblock %}
diff --git a/src/c3nav/control/templates/control/users.html b/src/c3nav/control/templates/control/users.html
index 2d786294..913bc4f4 100644
--- a/src/c3nav/control/templates/control/users.html
+++ b/src/c3nav/control/templates/control/users.html
@@ -8,7 +8,7 @@
- {% include 'control/fragment_pagination.html' with objects=users %}
+ {% include 'control/fragment_pagination.html' %}
@@ -23,5 +23,5 @@
{% endfor %}
- {% include 'control/fragment_pagination.html' with objects=users %}
+ {% include 'control/fragment_pagination.html' %}
{% endblock %}
diff --git a/src/c3nav/control/urls.py b/src/c3nav/control/urls.py
index da678d21..8e82e17e 100644
--- a/src/c3nav/control/urls.py
+++ b/src/c3nav/control/urls.py
@@ -1,16 +1,17 @@
from django.urls import path
-from c3nav.control.views import (announcement_detail, announcement_list, grant_access, grant_access_qr, main_index,
- map_updates, user_detail, user_list, mesh_node_list)
+from c3nav.control.views import (announcement_detail, announcement_list, grant_access, grant_access_qr, map_updates,
+ user_detail, MeshNodeListView, ControlPanelIndexView,
+ UserListView)
urlpatterns = [
- path('users/', user_list, name='control.users'),
+ path('users/', UserListView.as_view(), name='control.users'),
path('users//', user_detail, name='control.users.detail'),
path('access/', grant_access, name='control.access'),
path('access/', grant_access_qr, name='control.access.qr'),
path('announcements/', announcement_list, name='control.announcements'),
path('announcements//', announcement_detail, name='control.announcements.detail'),
path('mapupdates/', map_updates, name='control.map_updates'),
- path('mesh/', mesh_node_list, name='control.mesh_nodes'),
- path('', main_index, name='control.index'),
+ path('mesh/', MeshNodeListView.as_view(), name='control.mesh_nodes'),
+ path('', ControlPanelIndexView.as_view(), name='control.index'),
]
diff --git a/src/c3nav/control/views.py b/src/c3nav/control/views.py
index d459ee5d..4c686d56 100644
--- a/src/c3nav/control/views.py
+++ b/src/c3nav/control/views.py
@@ -6,6 +6,7 @@ from urllib.parse import urlencode
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import login_required
+from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.auth.models import User
from django.core.cache import cache
from django.core.exceptions import PermissionDenied
@@ -18,6 +19,7 @@ from django.utils import timezone
from django.utils.crypto import get_random_string
from django.utils.timezone import make_aware
from django.utils.translation import gettext_lazy as _
+from django.views.generic import TemplateView, ListView
from c3nav.control.forms import (AccessPermissionForm, AnnouncementForm, MapUpdateFilterForm, MapUpdateForm,
UserPermissionsForm, UserSpaceAccessForm)
@@ -29,6 +31,16 @@ from c3nav.mesh.models import MeshNode
from c3nav.site.models import Announcement
+class ControlPanelMixin(UserPassesTestMixin, LoginRequiredMixin):
+ login_url = 'site.login'
+ user_permission = None
+
+ def test_func(self):
+ if not self.user_permission:
+ return True
+ return getattr(self.request.user_permissions, self.user_permission)
+
+
def control_panel_view(func):
@wraps(func)
def wrapped_func(request, *args, **kwargs):
@@ -38,28 +50,23 @@ def control_panel_view(func):
return login_required(login_url='site.login')(wrapped_func)
-@login_required(login_url='site.login')
-@control_panel_view
-def main_index(request):
- return render(request, 'control/index.html', {})
+class ControlPanelIndexView(ControlPanelMixin, TemplateView):
+ template_name = "control/index.html"
-@login_required(login_url='site.login')
-@control_panel_view
-def user_list(request):
- search = request.GET.get('s')
- page = request.GET.get('page', 1)
+class UserListView(ControlPanelMixin, ListView):
+ model = User
+ paginate_by = 20
+ template_name = "control/users.html"
+ ordering = "id"
+ context_object_name = "users"
- queryset = User.objects.order_by('id')
- if search:
- queryset = queryset.filter(username__icontains=search.strip())
-
- paginator = Paginator(queryset, 20)
- users = paginator.page(page)
-
- return render(request, 'control/users.html', {
- 'users': users,
- })
+ def get_queryset(self):
+ qs = super().get_queryset()
+ search = self.request.GET.get('s')
+ if search:
+ qs = qs.filter(username__icontains=search.strip())
+ return qs
@login_required(login_url='site.login')
@@ -410,16 +417,8 @@ def map_updates(request):
})
-@login_required(login_url='site.login')
-@control_panel_view
-def mesh_node_list(request):
- page = request.GET.get('page', 1)
-
- queryset = MeshNode.objects.order_by('address')
-
- paginator = Paginator(queryset, 20)
- nodes = paginator.page(page)
-
- return render(request, 'control/mesh_nodes.html', {
- 'nodes': nodes,
- })
\ No newline at end of file
+class MeshNodeListView(ControlPanelMixin, ListView):
+ model = MeshNode
+ template_name = "control/mesh_nodes.html"
+ ordering = "address"
+ context_object_name = "nodes"