8000 Change sponsorship admin list view to exclude rejected ones by defaul… · python/pythondotorg@662ac4c · GitHub
[go: up one dir, main page]

Skip to content

Commit 662ac4c

Browse files
authored
Change sponsorship admin list view to exclude rejected ones by default (#2083)
1 parent 23762b9 commit 662ac4c

File tree

2 files changed

+87
-1
lines changed

2 files changed

+87
-1
lines changed

sponsors/admin.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,27 @@ def queryset(self, request, queryset):
263263
return queryset.filter(id__in=Subquery(qs))
264264

265265

266+
class SponsorshipStatusListFilter(admin.SimpleListFilter):
267+
title = "status"
268+
parameter_name = "status"
269+
270+
def lookups(self, request, model_admin):
271+
return Sponsorship.STATUS_CHOICES
272+
273+
def queryset(self, request, queryset):
274+
status = self.value()
275+
# exclude rejected ones by default
276+
if not status:
277+
return queryset.exclude(status=Sponsorship.REJECTED)
278+
return queryset.filter(status=status)
279+
280+
def choices(self, changelist):
281+
choices = list(super().choices(changelist))
282+
# replaces django default "All" text by a custom text
283+
choices[0]['display'] = "Applied / Approved / Finalized"
284+
return choices
285+
286+
266287
@admin.register(Sponsorship)
267288
class SponsorshipAdmin(admin.ModelAdmin):
268289
change_form_template = "sponsors/admin/sponsorship_change_form.html"
@@ -278,7 +299,7 @@ class SponsorshipAdmin(admin.ModelAdmin):
278299
"start_date",
279300
"end_date",
280301
]
281-
list_filter = ["status", "package", TargetableEmailBenefitsFilter]
302+
list_filter = [SponsorshipStatusListFilter, "package", TargetableEmailBenefitsFilter]
282303
actions = ["send_notifications"]
283304
fieldsets = [
284305
(

sponsors/tests/test_admin.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from unittest.mock import Mock
2+
3+
from django.contrib.admin.views.main import ChangeList
4+
from model_bakery import baker
5+
6+
from django.test import TestCase, RequestFactory
7+
8+
from sponsors.admin import SponsorshipStatusListFilter, SponsorshipAdmin
9+
from sponsors.models import Sponsorship
10+
11+
class TestCustomSponsorshipStatusListFilter(TestCase):
12+
13+
def setUp(self):
14+
self.request = RequestFactory().get("/")
15+
self.model_admin = SponsorshipAdmin
16+
self.filter = SponsorshipStatusListFilter(
17+
request=self.request,
18+
params={},
19+
model=Sponsorship,
20+
model_admin=self.model_admin
21+
)
22+
23+
def test_basic_configuration(self):
24+
self.assertEqual("status", self.filter.title)
25+
self.assertEqual("status", self.filter.parameter_name)
26+
self< 10000 /span>.assertIn(SponsorshipStatusListFilter, SponsorshipAdmin.list_filter)
27+
28+
def test_lookups(self):
29+
expected = [
30+
("applied", "Applied"),
31+
("rejected", "Rejected"),
32+
("approved", "Approved"),
33+
("finalized", "Finalized"),
34+
]
35+
self.assertEqual(expected, self.filter.lookups(self.request, self.model_admin))
36+
37+
def test_filter_queryset(self):
38+
sponsor = baker.make("sponsors.Sponsor")
39+
sponsorships = [
40+
baker.make(Sponsorship, status=Sponsorship.REJECTED, sponsor=sponsor),
41+
baker.make(Sponsorship, status=Sponsorship.APPLIED, sponsor=sponsor),
42+
baker.make(Sponsorship, status=Sponsorship.APPROVED, sponsor=sponsor),
43+
baker.make(Sponsorship, status=Sponsorship.FINALIZED, sponsor=sponsor),
44+
]
45+
46+
# filter by applied, approved and finalized status by default
47+
qs = self.filter.queryset(self.request, Sponsorship.objects.all())
48+
self.assertEqual(3, qs.count())
49+
self.assertNotIn(sponsorships[0], qs)
50+
51+
for sp in sponsorships:
52+
self.filter.used_parameters[self.filter.parameter_name] = sp.status
53+
qs = self.filter.queryset(self.request, Sponsorship.objects.all())
54+
self.assertEqual(1, qs.count())
55+
self.assertIn(sp, qs)
56+
57+
def test_choices_with_custom_text_for_all(self):
58+
lookups = self.filter.lookups(self.request, self.model_admin)
59+
changelist = Mock(ChangeList, autospec=True)
60+
choices = self.filter.choices(changelist)
61+
62+
self.assertEqual(len(choices), len(lookups) + 1)
63+
self.assertEqual(choices[0]["display"], "Applied / Approved / Finalized")
64+
for i, choice in enumerate(choices[1:]):
65+
self.assertEqual(choice["display"], lookups[i][1])

0 commit comments

Comments
 (0)
0