Extend members app: add filtering with django-filter, MemberFilter class, and initial view setup. Update URLs, templates, and dependencies for integration.

This commit is contained in:
2026-01-04 23:24:53 +01:00
parent e67ef526f4
commit 40ddab4627
14 changed files with 94 additions and 7 deletions

View File

@@ -45,6 +45,7 @@ INSTALLED_APPS = [
"django.contrib.staticfiles",
"constance",
"tailwind",
"django_filters",
"rules.apps.AutodiscoverRulesConfig",
"theme.apps.ThemeConfig", # Tailwind theme app
"members.apps.MembersConfig",

View File

@@ -15,8 +15,9 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.urls import include, path
urlpatterns = [
path('backend/', include('backend.urls')),
path('admin/', admin.site.urls),
]

View File

@@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

12
backend/members/urls.py Normal file
View File

@@ -0,0 +1,12 @@
from django.urls import include, path
from .views import MemberAddView, MemberDeleteView, MemberEditView, MemberListView, MemberLoadView
app_name = "members"
urlpatterns = [
path("", MemberListView.as_view(), name="list"),
# path("add/", MemberAddView.as_view(), name="add"),
# path("<int:pk>/edit/", MemberEditView.as_view(), name="edit"),
# path("<int:pk>/delete/", MemberDeleteView.as_view(), name="delete"),
# path("load/", MemberLoadView.as_view(), name="load"),
]

34
backend/members/views.py Normal file
View File

@@ -0,0 +1,34 @@
from typing import Any
from django.contrib import messages
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from django_filters.views import FilterView
from rules.contrib.views import PermissionRequiredMixin
from members.filters import MemberFilter
from members.models import Member
class MemberListView(PermissionRequiredMixin, FilterView):
filterset_class = MemberFilter
paginate_by = 50
permission_denied_message = _("You do not have permission to view this page.")
permission_required = "members.view_member"
def handle_no_permission(self) -> HttpResponseRedirect:
messages.error(self.request, self.get_permission_denied_message())
return HttpResponseRedirect(reverse_lazy("backend:index"))
class MemberAddView: ...
class MemberEditView: ...
class MemberDeleteView: ...
class MemberLoadView: ...

View File

@@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

9
backend/urls.py Normal file
View File

@@ -0,0 +1,9 @@
from django.urls import include, path
from .views import index
app_name = "backend"
urlpatterns = [
path("", index, name="index"),
path("members/", include("backend.members.urls")),
]

View File

@@ -1,3 +1,6 @@
from django.shortcuts import render
# Create your views here.
def index(request):
return render(request, "backend/index.html")

16
members/filters.py Normal file
View File

@@ -0,0 +1,16 @@
import django_filters
from django.utils.translation import gettext_lazy as _
from .models import Member
class MemberFilter(django_filters.FilterSet):
user__first_name = django_filters.CharFilter(field_name="user__first_name", label=_("First name"))
user__last_name = django_filters.CharFilter(field_name="user__last_name", label=_("Last name"))
license = django_filters.CharFilter(label=_("License"), lookup_expr="icontains")
class Meta:
model = Member
fields = ["user__first_name", "user__last_name", "license"]

View File

@@ -8,6 +8,7 @@ dependencies = [
"django>=6.0",
"django-constance>=4.3.4",
"django-extensions>=4.1",
"django-filter>=25.2",
"django-phonenumber-field[phonenumbers]>=8.4.0",
"django-tailwind[cookiecutter,honcho]>=4.4.2",
"psycopg2-binary>=2.9.11",

View File

@@ -0,0 +1 @@
TEST FILE

View File

@@ -0,0 +1 @@
TEST FILE 2

14
uv.lock generated
View File

@@ -243,6 +243,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/64/96/d967ca440d6a8e3861120f51985d8e5aec79b9a8bdda16041206adfe7adc/django_extensions-4.1-py3-none-any.whl", hash = "sha256:0699a7af28f2523bf8db309a80278519362cd4b6e1fd0a8cd4bf063e1e023336", size = 232980, upload-time = "2025-04-11T01:15:37.701Z" },
]
[[package]]
name = "django-filter"
version = "25.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2c/e4/465d2699cd388c0005fb8d6ae6709f239917c6d8790ac35719676fffdcf3/django_filter-25.2.tar.gz", hash = "sha256:760e984a931f4468d096f5541787efb8998c61217b73006163bf2f9523fe8f23", size = 143818, upload-time = "2025-10-05T09:51:31.521Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c1/40/6a02495c5658beb1f31eb09952d8aa12ef3c2a66342331ce3a35f7132439/django_filter-25.2-py3-none-any.whl", hash = "sha256:9c0f8609057309bba611062fe1b720b4a873652541192d232dd28970383633e3", size = 94145, upload-time = "2025-10-05T09:51:29.728Z" },
]
[[package]]
name = "django-phonenumber-field"
version = "8.4.0"
@@ -603,6 +615,7 @@ dependencies = [
{ name = "django" },
{ name = "django-constance" },
{ name = "django-extensions" },
{ name = "django-filter" },
{ name = "django-phonenumber-field", extra = ["phonenumbers"] },
{ name = "django-tailwind", extra = ["cookiecutter", "honcho"] },
{ name = "psycopg2-binary" },
@@ -622,6 +635,7 @@ requires-dist = [
{ name = "django", specifier = ">=6.0" },
{ name = "django-constance", specifier = ">=4.3.4" },
{ name = "django-extensions", specifier = ">=4.1" },
{ name = "django-filter", specifier = ">=25.2" },
{ name = "django-phonenumber-field", extras = ["phonenumbers"], specifier = ">=8.4.0" },
{ name = "django-tailwind", extras = ["cookiecutter", "honcho"], specifier = ">=4.4.2" },
{ name = "psycopg2-binary", specifier = ">=2.9.11" },