Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbe0e8b7

Browse files
authored
Enable admin users to edit benefits from sponsorship application via django admin (python#1710)
* New admin form to manage sponsorship's benefits* Can only edit benefits if sponsorship wasn't approved or rejected* black
1 parentb111092 commitbe0e8b7

File tree

4 files changed

+158
-10
lines changed

4 files changed

+158
-10
lines changed

‎sponsors/admin.py

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
LegalClause,
1919
)
2020
fromsponsorsimportuse_cases
21-
fromsponsors.formsimportSponsorshipReviewAdminForm
21+
fromsponsors.formsimportSponsorshipReviewAdminForm,SponsorBenefitAdminInlineForm
2222
fromsponsors.exceptionsimportSponsorshipInvalidStatusException
2323
fromcms.adminimportContentManageableModelAdmin
2424

@@ -94,10 +94,29 @@ class SponsorAdmin(ContentManageableModelAdmin):
9494

9595
classSponsorBenefitInline(admin.TabularInline):
9696
model=SponsorBenefit
97-
readonly_fields=["name","benefit_internal_value"]
98-
fields= ["name","benefit_internal_value"]
97+
form=SponsorBenefitAdminInlineForm
98+
fields= ["sponsorship_benefit","benefit_internal_value"]
9999
extra=0
100-
can_delete=False
100+
101+
defhas_add_permission(self,request):
102+
# this work around is necessary because the `obj` parameter was added to
103+
# InlineModelAdmin.has_add_permission only in Django 2.1.x and we're using 2.0.x
104+
has_add_permission=super().has_add_permission(request)
105+
match=request.resolver_match
106+
ifmatch.url_name=="sponsors_sponsorship_change":
107+
sponsorship=self.parent_model.objects.get(pk=match.kwargs["object_id"])
108+
has_add_permission=has_add_permissionandsponsorship.open_for_editing
109+
returnhas_add_permission
110+
111+
defget_readonly_fields(self,request,obj=None):
112+
ifobjandnotobj.open_for_editing:
113+
return ["sponsorship_benefit","benefit_internal_value"]
114+
return []
115+
116+
defhas_delete_permission(self,request,obj=None):
117+
ifnotobj:
118+
returnTrue
119+
returnobj.open_for_editing
101120

102121

103122
@admin.register(Sponsorship)
@@ -265,17 +284,19 @@ def get_sponsor_primary_phone(self, obj):
265284

266285
defget_sponsor_mailing_address(self,obj):
267286
sponsor=obj.sponsor
268-
city_row=f'{sponsor.city} -{sponsor.get_country_display()} ({sponsor.country})'
287+
city_row= (
288+
f"{sponsor.city} -{sponsor.get_country_display()} ({sponsor.country})"
289+
)
269290
ifsponsor.state:
270-
city_row=f'{sponsor.city} -{sponsor.state} -{sponsor.get_country_display()} ({sponsor.country})'
291+
city_row=f"{sponsor.city} -{sponsor.state} -{sponsor.get_country_display()} ({sponsor.country})"
271292

272293
mail_row=sponsor.mailing_address_line_1
273294
ifsponsor.mailing_address_line_2:
274-
mail_row+=f' -{sponsor.mailing_address_line_2}'
295+
mail_row+=f" -{sponsor.mailing_address_line_2}"
275296

276-
html=f'<p>{city_row}</p>'
277-
html+=f'<p>{mail_row}</p>'
278-
html+=f'<p>{sponsor.postal_code}</p>'
297+
html=f"<p>{city_row}</p>"
298+
html+=f"<p>{mail_row}</p>"
299+
html+=f"<p>{sponsor.postal_code}</p>"
279300
returnmark_safe(html)
280301

281302
get_sponsor_mailing_address.short_description="Mailing/Billing Address"

‎sponsors/forms.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
Sponsor,
1414
SponsorContact,
1515
Sponsorship,
16+
SponsorBenefit,
1617
)
1718

1819

@@ -331,3 +332,40 @@ def clean(self):
331332
raiseforms.ValidationError("End date must be greater than start date")
332333

333334
returncleaned_data
335+
336+
337+
classSponsorBenefitAdminInlineForm(forms.ModelForm):
338+
sponsorship_benefit=forms.ModelChoiceField(
339+
queryset=SponsorshipBenefit.objects.select_related("program"),
340+
)
341+
342+
def__init__(self,*args,**kwargs):
343+
super().__init__(*args,**kwargs)
344+
if"benefit_internal_value"inself.fields:
345+
self.fields["benefit_internal_value"].required=True
346+
347+
classMeta:
348+
model=SponsorBenefit
349+
fields= ["sponsorship_benefit","sponsorship","benefit_internal_value"]
350+
351+
defsave(self,commit=True):
352+
sponsorship=self.cleaned_data["sponsorship"]
353+
benefit=self.cleaned_data["sponsorship_benefit"]
354+
value=self.cleaned_data["benefit_internal_value"]
355+
356+
ifnot (self.instanceandself.instance.pk):# new benefit
357+
self.instance=SponsorBenefit(sponsorship=sponsorship)
358+
else:
359+
self.instance.refresh_from_db()
360+
361+
self.instance.benefit_internal_value=value
362+
ifbenefit.pk!=self.instance.sponsorship_benefit_id:
363+
self.instance.sponsorship_benefit=benefit
364+
self.instance.name=benefit.name
365+
self.instance.description=benefit.description
366+
self.instance.program=benefit.program
367+
368+
ifcommit:
369+
self.instance.save()
370+
371+
returnself.instance

‎sponsors/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,10 @@ def package_benefits(self):
361361
defadded_benefits(self):
362362
returnself.benefits.filter(added_by_user=True)
363363

364+
@property
365+
defopen_for_editing(self):
366+
returnself.status==self.APPLIED
367+
364368
@property
365369
defnext_status(self):
366370
states_map= {

‎sponsors/tests/test_forms.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
SponsorContact,
1010
Sponsor,
1111
SponsorContactFormSet,
12+
SponsorBenefitAdminInlineForm,
13+
SponsorBenefit,
14+
Sponsorship,
1215
)
1316
fromsponsors.modelsimportSponsorshipBenefit,SponsorContact
1417
from .utilsimportget_static_image_file_as_upload
@@ -355,3 +358,85 @@ def test_invalidate_formset_if_no_form(self):
355358
self.data["contact-TOTAL_FORMS"]=0
356359
formset=SponsorContactFormSet(self.data,prefix="contact")
357360
self.assertFalse(formset.is_valid())
361+
362+
363+
classSponsorBenefitAdminInlineFormTests(TestCase):
364+
defsetUp(self):
365+
self.benefit=baker.make(SponsorshipBenefit)
366+
self.sponsorship=baker.make(Sponsorship)
367+
self.data= {
368+
"sponsorship_benefit":self.benefit.pk,
369+
"sponsorship":self.sponsorship.pk,
370+
"benefit_internal_value":200,
371+
}
372+
373+
deftest_required_fields_for_new_sponsor_benefit(self):
374+
required_fields= [
375+
"sponsorship_benefit",
376+
"sponsorship",
377+
"benefit_internal_value",
378+
]
379+
380+
form=SponsorBenefitAdminInlineForm({})
381+
self.assertFalse(form.is_valid())
382+
383+
forrequiredinrequired_fields:
384+
self.assertIn(required,form.errors)
385+
self.assertEqual(len(required_fields),len(form.errors))
386+
387+
deftest_create_new_sponsor_benefit_for_sponsorship(self):
388+
form=SponsorBenefitAdminInlineForm(data=self.data)
389+
self.assertTrue(form.is_valid(),form.errors)
390+
391+
sponsor_benefit=form.save()
392+
sponsor_benefit.refresh_from_db()
393+
394+
self.assertEqual(sponsor_benefit.sponsorship,self.sponsorship)
395+
self.assertEqual(sponsor_benefit.sponsorship_benefit,self.benefit)
396+
self.assertEqual(sponsor_benefit.name,self.benefit.name)
397+
self.assertEqual(sponsor_benefit.description,self.benefit.description)
398+
self.assertEqual(sponsor_benefit.program,self.benefit.program)
399+
self.assertEqual(sponsor_benefit.benefit_internal_value,200)
400+
401+
deftest_update_existing_sponsor_benefit(self):
402+
sponsor_benefit=baker.make(
403+
SponsorBenefit,
404+
sponsorship=self.sponsorship,
405+
sponsorship_benefit=self.benefit,
406+
)
407+
new_benefit=baker.make(SponsorshipBenefit)
408+
self.data["sponsorship_benefit"]=new_benefit.pk
409+
410+
form=SponsorBenefitAdminInlineForm(data=self.data,instance=sponsor_benefit)
411+
self.assertTrue(form.is_valid(),form.errors)
412+
form.save()
413+
sponsor_benefit.refresh_from_db()
414+
415+
self.assertEqual(1,SponsorBenefit.objects.count())
416+
self.assertEqual(sponsor_benefit.sponsorship,self.sponsorship)
417+
self.assertEqual(sponsor_benefit.sponsorship_benefit,new_benefit)
418+
self.assertEqual(sponsor_benefit.name,new_benefit.name)
419+
self.assertEqual(sponsor_benefit.description,new_benefit.description)
420+
self.assertEqual(sponsor_benefit.program,new_benefit.program)
421+
self.assertEqual(sponsor_benefit.benefit_internal_value,200)
422+
423+
deftest_do_not_update_sponsorship_if_it_doesn_change(self):
424+
sponsor_benefit=baker.make(
425+
SponsorBenefit,
426+
sponsorship=self.sponsorship,
427+
sponsorship_benefit=self.benefit,
428+
)
429+
new_benefit=baker.make(SponsorshipBenefit)
430+
431+
form=SponsorBenefitAdminInlineForm(data=self.data,instance=sponsor_benefit)
432+
self.assertTrue(form.is_valid(),form.errors)
433+
form.save()
434+
sponsor_benefit.refresh_from_db()
435+
self.benefit.name="new name"
436+
self.benefit.save()
437+
438+
self.assertEqual(1,SponsorBenefit.objects.count())
439+
self.assertEqual(sponsor_benefit.sponsorship,self.sponsorship)
440+
self.assertEqual(sponsor_benefit.sponsorship_benefit,self.benefit)
441+
self.assertNotEqual(sponsor_benefit.name,"new name")
442+
self.assertEqual(sponsor_benefit.benefit_internal_value,200)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp