Activate member deletion functionality: implement MemberDeleteView with HTMX integration, add is_active filter, update member filter template, and refine related styles.
This commit is contained in:
@@ -7,6 +7,6 @@ urlpatterns = [
|
|||||||
path("", MemberListView.as_view(), name="list"),
|
path("", MemberListView.as_view(), name="list"),
|
||||||
# path("add/", MemberAddView.as_view(), name="add"),
|
# path("add/", MemberAddView.as_view(), name="add"),
|
||||||
# path("<int:pk>/edit/", MemberEditView.as_view(), name="edit"),
|
# path("<int:pk>/edit/", MemberEditView.as_view(), name="edit"),
|
||||||
# path("<int:pk>/delete/", MemberDeleteView.as_view(), name="delete"),
|
path("<int:pk>/delete/", MemberDeleteView.as_view(), name="delete"),
|
||||||
# path("load/", MemberLoadView.as_view(), name="load"),
|
# path("load/", MemberLoadView.as_view(), name="load"),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.views.generic import DeleteView
|
||||||
from django_filters.views import FilterView
|
from django_filters.views import FilterView
|
||||||
from rules.contrib.views import PermissionRequiredMixin
|
from rules.contrib.views import PermissionRequiredMixin
|
||||||
|
|
||||||
@@ -21,6 +23,17 @@ class MemberListView(HTMXViewMixin, PermissionRequiredMixin, FilterView):
|
|||||||
def handle_no_permission(self) -> HttpResponseRedirect:
|
def handle_no_permission(self) -> HttpResponseRedirect:
|
||||||
messages.error(self.request, self.get_permission_denied_message())
|
messages.error(self.request, self.get_permission_denied_message())
|
||||||
return HttpResponseRedirect(reverse_lazy("backend:index"))
|
return HttpResponseRedirect(reverse_lazy("backend:index"))
|
||||||
|
|
||||||
|
def get_filterset_kwargs(self, filterset_class) -> dict[str, Any]:
|
||||||
|
kwargs = super().get_filterset_kwargs(filterset_class)
|
||||||
|
|
||||||
|
filter_values = {} if kwargs["data"] is None else kwargs["data"].dict()
|
||||||
|
|
||||||
|
if not filter_values:
|
||||||
|
filter_values.update({"user__is_active": "true"})
|
||||||
|
|
||||||
|
kwargs["data"] = filter_values
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
class MemberAddView: ...
|
class MemberAddView: ...
|
||||||
@@ -29,7 +42,26 @@ class MemberAddView: ...
|
|||||||
class MemberEditView: ...
|
class MemberEditView: ...
|
||||||
|
|
||||||
|
|
||||||
class MemberDeleteView: ...
|
class MemberDeleteView(HTMXViewMixin, PermissionRequiredMixin, SuccessMessageMixin, DeleteView):
|
||||||
|
model = Member
|
||||||
|
success_message = _("Member <strong>%(name)s</strong> has been deleted successfully.")
|
||||||
|
permission_required = "members.delete_member"
|
||||||
|
permission_denied_message = _("You do not have permission to view this page.")
|
||||||
|
success_url = reverse_lazy("backend:members:list")
|
||||||
|
|
||||||
|
def handle_no_permission(self) -> HttpResponseRedirect:
|
||||||
|
messages.error(self.request, self.get_permission_denied_message())
|
||||||
|
return HttpResponseRedirect(reverse_lazy("backend:index"))
|
||||||
|
|
||||||
|
def get_success_message(self, cleaned_data):
|
||||||
|
return self.success_message % dict(cleaned_data, name=self.object.user.get_full_name())
|
||||||
|
|
||||||
|
def delete(self, request, *args, **kwargs) -> HttpResponseRedirect:
|
||||||
|
self.object = self.get_object()
|
||||||
|
self.object.user.is_active = False
|
||||||
|
self.object.user.save()
|
||||||
|
|
||||||
|
return HttpResponseRedirect(self.get_success_url())
|
||||||
|
|
||||||
|
|
||||||
class MemberLoadView: ...
|
class MemberLoadView: ...
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ class HTMXPartialMixin:
|
|||||||
|
|
||||||
class HTMXViewMixin:
|
class HTMXViewMixin:
|
||||||
"""
|
"""
|
||||||
A full featured HTMX integration mixin for Django CBVs.
|
A full-featured HTMX integration mixin for Django CBVs.
|
||||||
Supports:
|
Supports:
|
||||||
- partial rendering via django-partials
|
- partial rendering via django-partials
|
||||||
- HX-Redirect
|
- HX-Redirect
|
||||||
- HX-Push-URL
|
- HX-Push-URL
|
||||||
- HX-Trigger events
|
- HX-Trigger events
|
||||||
- HX-Refresh
|
- HX-Refresh
|
||||||
- Graceful fallback to normal DJango rendering
|
- Graceful fallback to normal Django rendering
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Name of the partial block: template.html#partial_name
|
# Name of the partial block: template.html#partial_name
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ class MemberFilter(django_filters.FilterSet):
|
|||||||
user__first_name = django_filters.CharFilter(field_name="user__first_name", label=_("First name"), lookup_expr="icontains")
|
user__first_name = django_filters.CharFilter(field_name="user__first_name", label=_("First name"), lookup_expr="icontains")
|
||||||
user__last_name = django_filters.CharFilter(field_name="user__last_name", label=_("Last name"), lookup_expr="icontains")
|
user__last_name = django_filters.CharFilter(field_name="user__last_name", label=_("Last name"), lookup_expr="icontains")
|
||||||
license = django_filters.CharFilter(label=_("License"), lookup_expr="icontains")
|
license = django_filters.CharFilter(label=_("License"), lookup_expr="icontains")
|
||||||
|
user__is_active = django_filters.TypedChoiceFilter( field_name='user__is_active', label=_("Active?"), initial="true", choices=( ('', 'All'), ('true', 'Yes'), ('false', 'No'), ), coerce=lambda x: x.lower() == 'true' )
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Member
|
model = Member
|
||||||
fields = ["user__first_name", "user__last_name", "license"]
|
fields = ["user__first_name", "user__last_name", "license", "user__is_active"]
|
||||||
|
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@
|
|||||||
<i class="fa-solid fa-eye"></i>{% translate "Details" %}
|
<i class="fa-solid fa-eye"></i>{% translate "Details" %}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a class="btn btn-outline btn-error btn-sm" href="">
|
<a class="btn btn-outline btn-error btn-sm" href="{% url "backend:members:delete" member.pk %}">
|
||||||
<i class="fa-solid fa-trash"></i>{% translate "Delete" %}
|
<i class="fa-solid fa-trash"></i>{% translate "Delete" %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@source inline("input-{xs,sm,md,lg,xl}");
|
@source inline("input-{xs,sm,md,lg,xl}");
|
||||||
|
@source inline("select-{xs,sm,md,lg,xl}");
|
||||||
|
|
||||||
@layer components {
|
@layer components {
|
||||||
h1.page-title {
|
h1.page-title {
|
||||||
|
|||||||
Reference in New Issue
Block a user