diff --git a/src/country_workspace/admin/batch.py b/src/country_workspace/admin/batch.py index a75752c..9fd0d0d 100644 --- a/src/country_workspace/admin/batch.py +++ b/src/country_workspace/admin/batch.py @@ -3,7 +3,6 @@ from admin_extra_buttons.buttons import LinkButton from admin_extra_buttons.decorators import link -from adminfilters.autocomplete import LinkedAutoCompleteFilter from ..models import Batch from .base import BaseModelAdmin @@ -11,10 +10,12 @@ @admin.register(Batch) class BatchAdmin(BaseModelAdmin): - list_display = ("name", "import_date", "imported_by") + list_display = ("name", "import_date", "imported_by", "program") list_filter = ( - ("country_office", LinkedAutoCompleteFilter.factory(parent=None)), - ("program", LinkedAutoCompleteFilter.factory(parent="country_office")), + "country_office", + "program", + # ("country_office", LinkedAutoCompleteFilter.factory(parent=None)), + # ("program", LinkedAutoCompleteFilter.factory(parent="country_office")), ) readonly_fields = ("country_office", "program") search_fields = ("name",) diff --git a/src/country_workspace/admin/household.py b/src/country_workspace/admin/household.py index aafb87d..405c4d0 100644 --- a/src/country_workspace/admin/household.py +++ b/src/country_workspace/admin/household.py @@ -3,6 +3,7 @@ from admin_extra_buttons.buttons import LinkButton from admin_extra_buttons.decorators import link +from adminfilters.autocomplete import LinkedAutoCompleteFilter from ..models import Household from .base import BaseModelAdmin @@ -10,11 +11,12 @@ @admin.register(Household) class HouseholdAdmin(BaseModelAdmin): - list_display = ("name", "batch") - # list_filter = ( - # ("batch__country_office", LinkedAutoCompleteFilter.factory(parent=None)), - # ("batch__program", LinkedAutoCompleteFilter.factory(parent="batch__country_office")), - # ) + list_display = ("name", "country_office", "program", "batch") + list_filter = ( + ("batch__country_office", LinkedAutoCompleteFilter.factory(parent=None)), + ("batch__program", LinkedAutoCompleteFilter.factory(parent="batch__country_office")), + ("batch", LinkedAutoCompleteFilter.factory(parent="batch__program")), + ) # readonly_fields = ("country_office", "program") search_fields = ("name",) diff --git a/src/country_workspace/web/templates/workspace/hh_ind_change_list.html b/src/country_workspace/web/templates/workspace/hh_ind_change_list.html index 03a9959..374a885 100644 --- a/src/country_workspace/web/templates/workspace/hh_ind_change_list.html +++ b/src/country_workspace/web/templates/workspace/hh_ind_change_list.html @@ -11,6 +11,7 @@
  • No checker found. Please check your Program configuration.
  • {% endif %} + {{ block.super }} {% endblock messages %} {% block content %} diff --git a/src/country_workspace/workspaces/admin/batch.py b/src/country_workspace/workspaces/admin/batch.py index 7411e3c..0cac29a 100644 --- a/src/country_workspace/workspaces/admin/batch.py +++ b/src/country_workspace/workspaces/admin/batch.py @@ -6,9 +6,9 @@ from admin_extra_buttons.buttons import LinkButton from admin_extra_buttons.decorators import link -from adminfilters.autocomplete import LinkedAutoCompleteFilter from ...state import state +from ..filters import CWLinkedAutoCompleteFilter from ..models import CountryBatch from ..options import WorkspaceModelAdmin from .hh_ind import SelectedProgramMixin @@ -17,7 +17,7 @@ pass -class ProgramBatchFilter(LinkedAutoCompleteFilter): +class ProgramBatchFilter(CWLinkedAutoCompleteFilter): def queryset(self, request: HttpRequest, queryset: QuerySet) -> QuerySet: if self.lookup_val: diff --git a/src/country_workspace/workspaces/admin/hh_ind.py b/src/country_workspace/workspaces/admin/hh_ind.py index f535732..bf05035 100644 --- a/src/country_workspace/workspaces/admin/hh_ind.py +++ b/src/country_workspace/workspaces/admin/hh_ind.py @@ -34,6 +34,8 @@ def get_selected_program(self, request: HttpRequest, obj: "Optional[Validable]" selected_program = None if obj: selected_program = obj.batch.program + if "program" in request.GET: + selected_program = CountryProgram.objects.get(pk=request.GET["program"]) elif "program__exact" in request.GET: selected_program = CountryProgram.objects.get(pk=request.GET["program__exact"]) elif "batch__program__exact" in request.GET: @@ -76,8 +78,11 @@ def changelist_view(self, request: HttpRequest, extra_context: Optional[dict[str class BeneficiaryBaseAdmin(AdminAutoCompleteSearchMixin, SelectedProgramMixin, WorkspaceModelAdmin): list_filter = ( + # ("batch__country_office", LinkedAutoCompleteFilter.factory(parent=None)), ("batch__program", LinkedAutoCompleteFilter.factory(parent=None)), ("batch", LinkedAutoCompleteFilter.factory(parent="batch__program")), + # ("batch__program", LinkedAutoCompleteFilter.factory(parent=None)), + # ("batch", LinkedAutoCompleteFilter.factory(parent="batch__program")), # ("batch", BatchFilter), ) actions = ["validate_queryset", actions.mass_update, actions.regex_update] diff --git a/src/country_workspace/workspaces/filters.py b/src/country_workspace/workspaces/filters.py index 792642e..f510484 100644 --- a/src/country_workspace/workspaces/filters.py +++ b/src/country_workspace/workspaces/filters.py @@ -7,7 +7,46 @@ from country_workspace.state import state -class ProgramFilter(LinkedAutoCompleteFilter): +class CWLinkedAutoCompleteFilter(LinkedAutoCompleteFilter): + def __init__(self, field, request, params, model, model_admin, field_path): + self.dependants = [] + if self.parent and not self.parent_lookup_kwarg: + self.parent_lookup_kwarg = f"{self.parent}__exact" + super().__init__(field, request, params, model, model_admin, field_path) + for pos, entry in enumerate(model_admin.list_filter): + if isinstance(entry, (list, tuple)): + if ( + len(entry) == 2 + and entry[0] != self.field_path + and entry[1].__name__ == type(self).__name__ + and entry[1].parent == self.field_path + ): + kwarg = f"{entry[0]}__exact" + if entry[1].parent: + if kwarg not in self.dependants: + self.dependants.extend(entry[1].dependants) + self.dependants.append(kwarg) + + def get_url(self): + url = reverse("%s:autocomplete" % self.admin_site.name) + if self.parent_lookup_kwarg in self.request.GET: + flt = self.parent_lookup_kwarg.split("__")[-2] + oid = self.request.GET[self.parent_lookup_kwarg] + return f"{url}?{flt}={oid}" + return url + + # @classmethod + # def factory(cls, **kwargs): + # kwargs.setdefault(**{ + # "filter_title": None, + # "lookup_name": "exact", + # }) + # # kwargs["filter_title"] = title + # # kwargs["lookup_name"] = lookup_name + # return type("LinkedAutoCompleteFilter", (cls,), kwargs) + + +class ProgramFilter(CWLinkedAutoCompleteFilter): def queryset(self, request: HttpRequest, queryset: QuerySet) -> QuerySet: if self.lookup_val: @@ -17,7 +56,7 @@ def queryset(self, request: HttpRequest, queryset: QuerySet) -> QuerySet: return queryset -class BatchFilter(LinkedAutoCompleteFilter): +class BatchFilter(CWLinkedAutoCompleteFilter): def has_output(self) -> bool: return bool("batch__program__exact" in self.request.GET) @@ -39,12 +78,12 @@ def queryset(self, request: HttpRequest, queryset: QuerySet) -> QuerySet: return queryset -class HouseholdFilter(LinkedAutoCompleteFilter): +class HouseholdFilter(CWLinkedAutoCompleteFilter): fk_name = "name" - def __init__(self, field: str, request: HttpRequest, params, model, model_admin, field_path): - self.request = request - super().__init__(field, request, params, model, model_admin, field_path) + # def __init__(self, field: str, request: HttpRequest, params, model, model_admin, field_path): + # self.request = request + # super().__init__(field, request, params, model, model_admin, field_path) def has_output(self) -> bool: return bool(self.selected_program()) diff --git a/src/country_workspace/workspaces/sites.py b/src/country_workspace/workspaces/sites.py index 0284702..cd31200 100644 --- a/src/country_workspace/workspaces/sites.py +++ b/src/country_workspace/workspaces/sites.py @@ -5,7 +5,7 @@ from django.apps import apps from django.contrib import admin from django.core.exceptions import FieldDoesNotExist, PermissionDenied -from django.db.models import Model, QuerySet +from django.db.models import QuerySet from django.http import Http404, HttpRequest, HttpResponse, HttpResponseRedirect from django.shortcuts import redirect from django.template.response import TemplateResponse @@ -23,8 +23,8 @@ class TenantAutocompleteJsonView(SmartAutocompleteJsonView): # - def has_perm(self, request: "HttpRequest", obj: "Model|None" = None) -> bool: - return self.model_admin.has_view_permission(request, obj=obj) + # def has_perm(self, request: "HttpRequest", obj: "Model|None" = None) -> bool: + # return self.model_admin.has_view_permission(request, obj=obj) def filter_queryset(self, queryset: QuerySet) -> QuerySet: params = {