diff --git a/src/memberdb/admin.py b/src/memberdb/admin.py index 142d0a425e3efe7308979d7f7632efbd2965c171..ab359115c08b92e25de120b0fdd71d89608137be 100644 --- a/src/memberdb/admin.py +++ b/src/memberdb/admin.py @@ -1,3 +1,5 @@ +from datetime import datetime + from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render from django.urls import path, reverse @@ -15,6 +17,33 @@ from memberdb.account import AccountForm, AccountView def get_model_url(pk, model_name): return reverse('admin:memberdb_%s_change' % model_name, args=[pk]) +class MembershipRenewalFilter(admin.SimpleListFilter): + """ allow filtering Member records by renewal year / status """ + """ see https://docs.djangoproject.com/en/2.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter """ + title = 'Last renewal' + parameter_name = 'renewed' + + def lookups(self, request, modeladmin): + """ returns a list of tuples """ + # hardcode the starting year, since otherwise you need a fairly complex query + start_year = 2019 + year = datetime.now().year + 1 + return [ (str(x), str(x)) for x in range(start_year, year) ] + [ ('none', 'Never renewed') ] + + def queryset(self, request, queryset): + """ returns the filtered queryset based on the value passed to the request """ + if self.value() is None: + # return the original queryset when parameter not specified + return queryset + + if self.value() == 'none': + # filter by finding a condition that will never be true for reverse relation (child) + # objects that exist, since you can't filter by "has no children" + return queryset.filter(memberships__id__isnull=True) + + # filter via attributes on children / reverse relation (hurrah!) + return queryset.filter(memberships__date_submitted__year=int(self.value())) + class ReadOnlyModelAdmin(admin.ModelAdmin): """ helper mixin to make the admin page display only "View" rather than "Change" or "Add" """ def has_add_permission(self, request): @@ -50,7 +79,7 @@ class MembershipInline(admin.TabularInline): class MemberAdmin(admin.ModelAdmin): list_display = ['first_name', 'last_name', 'display_name', 'username'] - list_filter = ['is_guild', 'is_student'] + list_filter = ['is_guild', 'is_student', MembershipRenewalFilter] readonly_fields = ['member_updated', 'updated', 'created'] search_fields = list_display actions = [download_as_csv]