Skip to content

Commit

Permalink
Eliminate different model forms for the same model
Browse files Browse the repository at this point in the history
Changes:
- Introduce the WidgetOverrideMixin to change widgets at form initialization
- Move from using selectable fields to selectable widgets. I faced problems while overriding widgets for selectable fields.
  • Loading branch information
aditnryn committed Dec 18, 2016
1 parent 906f45e commit d014dd9
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 133 deletions.
4 changes: 2 additions & 2 deletions pydata/forms.py
@@ -1,6 +1,6 @@
from django import forms

from workshops.forms import TaskFullForm, SponsorshipForm, BootstrapHelper
from workshops.forms import TaskForm, SponsorshipForm, BootstrapHelper
from workshops.models import Person, Task, Sponsorship


Expand Down Expand Up @@ -52,7 +52,7 @@ class PersonAddFormSet(BaseModelAddFormSet):

class TaskAddFormSet(BaseModelAddFormSet):
model = Task
form = TaskFullForm
form = TaskForm


class SponsorshipAddFormSet(BaseModelAddFormSet):
Expand Down
149 changes: 44 additions & 105 deletions workshops/forms.py
Expand Up @@ -41,6 +41,7 @@
TrainingProgress,
)


class BootstrapHelper(FormHelper):
"""Layout and behavior for crispy-displayed forms."""
html5_required = True
Expand Down Expand Up @@ -166,6 +167,15 @@ class PrivacyConsentMixin(forms.Form):
required=True)


class WidgetOverrideMixin:

def __init__(self, *args, **kwargs):
widgets = kwargs.pop('widgets', {})
super().__init__(*args, **kwargs)
for field, widget in widgets.items():
self.fields[field].widget = widget


class WorkshopStaffForm(forms.Form):
'''Represent instructor matching form.'''

Expand Down Expand Up @@ -437,35 +447,21 @@ class Media:
)


class TaskForm(forms.ModelForm):

person = selectable.AutoCompleteSelectField(
lookup_class=lookups.PersonLookup,
label='Person',
required=True,
widget=selectable.AutoComboboxSelectWidget,
)
class TaskForm(WidgetOverrideMixin, forms.ModelForm):

helper = BootstrapHelper(submit_label='Add')

class Meta:
model = Task
fields = '__all__'
widgets = {'event': HiddenInput}


class TaskFullForm(TaskForm):

event = selectable.AutoCompleteSelectField(
lookup_class=lookups.EventLookup,
label='Event',
required=True,
widget=selectable.AutoComboboxSelectWidget,
)

class Meta:
model = Task
fields = '__all__'
widgets = {
'person': selectable.AutoComboboxSelectWidget(
lookup_class=lookups.PersonLookup,
),
'event': selectable.AutoComboboxSelectWidget(
lookup_class=lookups.EventLookup,
),
}


class PersonForm(forms.ModelForm):
Expand All @@ -483,7 +479,7 @@ class PersonForm(forms.ModelForm):
widget=selectable.AutoComboboxSelectMultipleWidget,
)

helper = BootstrapHelper(form_id='person-edit-form')
helper = bootstrap_helper

class Meta:
model = Person
Expand Down Expand Up @@ -619,76 +615,24 @@ class PersonsMergeForm(forms.Form):
)


class BadgeAwardForm(forms.ModelForm):

person = selectable.AutoCompleteSelectField(
lookup_class=lookups.PersonLookup,
label='Person',
required=True,
widget=selectable.AutoComboboxSelectWidget,
)

event = selectable.AutoCompleteSelectField(
lookup_class=lookups.EventLookup,
label='Event',
required=False,
widget=selectable.AutoComboboxSelectWidget,
)

awarded_by = selectable.AutoCompleteSelectField(
lookup_class=lookups.PersonLookup,
label='Awarded by',
required=False,
widget=selectable.AutoComboboxSelectWidget,
)
class AwardForm(WidgetOverrideMixin, forms.ModelForm):

helper = bootstrap_helper

class Meta:
model = Award
fields = '__all__'
widgets = {'badge': HiddenInput}


class PersonAwardForm(forms.ModelForm):

event = selectable.AutoCompleteSelectField(
lookup_class=lookups.EventLookup,
label='Event',
required=False,
widget=selectable.AutoComboboxSelectWidget,
)

awarded_by = selectable.AutoCompleteSelectField(
lookup_class=lookups.PersonLookup,
label='Awarded by',
required=False,
widget=selectable.AutoComboboxSelectWidget,
)

helper = BootstrapHelper(submit_label='Add', form_id='person-awards-form')

class Meta:
model = Award
fields = '__all__'
widgets = {'person': HiddenInput}


class PersonTaskForm(forms.ModelForm):

event = selectable.AutoCompleteSelectField(
lookup_class=lookups.EventLookup,
label='Event',
required=True,
widget=selectable.AutoComboboxSelectWidget,
)

helper = BootstrapHelper(submit_label='Add', form_id='person-tasks-form')

class Meta:
model = Task
fields = '__all__'
widgets = {'person': HiddenInput}
widgets = {
'person': selectable.AutoComboboxSelectWidget(
lookup_class=lookups.PersonLookup,
),
'event': selectable.AutoComboboxSelectWidget(
lookup_class=lookups.EventLookup,
),
'awarded_by': selectable.AutoComboboxSelectWidget(
lookup_class=lookups.PersonLookup,
),
}


class OrganizationForm(forms.ModelForm):
Expand Down Expand Up @@ -722,31 +666,26 @@ class MembershipForm(forms.ModelForm):
class Meta:
model = Membership
fields = '__all__'
widgets = {'host': HiddenInput, }


class SponsorshipForm(forms.ModelForm):
organization = selectable.AutoCompleteSelectField(
lookup_class=lookups.OrganizationLookup,
label='Organization',
required=True,
help_text=Sponsorship._meta.get_field('organization').help_text,
widget=selectable.AutoComboboxSelectWidget,
)

contact = selectable.AutoCompleteSelectField(
lookup_class=lookups.PersonLookup,
label='Contact',
required=False,
widget=selectable.AutoComboboxSelectWidget,
)
class SponsorshipForm(WidgetOverrideMixin, forms.ModelForm):

helper = BootstrapHelper(submit_label='Add')

class Meta:
model = Sponsorship
fields = '__all__'
widgets = {'event': HiddenInput, }
widgets = {
'organization': selectable.AutoComboboxSelectWidget(
lookup_class=lookups.OrganizationLookup,
),
'event': selectable.AutoComboboxSelectWidget(
lookup_class=lookups.EventLookup,
),
'contact': selectable.AutoComboboxSelectWidget(
lookup_class=lookups.PersonLookup,
)
}


class SWCEventRequestForm(PrivacyConsentMixin, forms.ModelForm):
Expand Down
12 changes: 6 additions & 6 deletions workshops/test/test_person.py
Expand Up @@ -470,22 +470,22 @@ def test_awarding_instructor_badge_workflow(self):

# Test workflow starting from clicking at "SWC" label
swc_res = trainees.click('^SWC$')
self.assertSelected(swc_res.forms['person-awards-form']['award-badge'],
self.assertSelected(swc_res.forms[2]['award-badge'],
'Software Carpentry Instructor')
self.assertEqual(swc_res.forms['person-awards-form']['award-event_0'].value,
self.assertEqual(swc_res.forms[2]['award-event_0'].value,
'2016-08-10-training')
swc_res = swc_res.forms['person-awards-form'].submit().follow()
swc_res = swc_res.forms[2].submit().follow()
self.assertIn("Bob Smith <bob.smith@example.com> was awarded "
"Software Carpentry Instructor badge.", swc_res)
self.assertEqual(trainees.request.url, swc_res.request.url)

# Test workflow starting from clicking at "DC" label
dc_res = trainees.click('^DC$')
self.assertSelected(dc_res.forms['person-awards-form']['award-badge'],
self.assertSelected(dc_res.forms[2]['award-badge'],
'Data Carpentry Instructor')
self.assertEqual(dc_res.forms['person-awards-form']['award-event_0'].value,
self.assertEqual(dc_res.forms[2]['award-event_0'].value,
'2016-08-10-training')
dc_res = dc_res.forms['person-awards-form'].submit().follow()
dc_res = dc_res.forms[2].submit().follow()
self.assertIn("Bob Smith <bob.smith@example.com> was awarded "
"Data Carpentry Instructor badge.", dc_res)
self.assertEqual(trainees.request.url, dc_res.request.url)
Expand Down
45 changes: 25 additions & 20 deletions workshops/views.py
Expand Up @@ -29,6 +29,7 @@
Prefetch,
)
from django.db.models.functions import Now
from django.forms import HiddenInput
from django.http import Http404, HttpResponse, JsonResponse
from django.http import HttpResponseBadRequest
from django.shortcuts import redirect, render, get_object_or_404
Expand Down Expand Up @@ -79,12 +80,9 @@
PersonBulkAddForm,
EventForm,
TaskForm,
TaskFullForm,
BadgeAwardForm,
PersonAwardForm,
AwardForm,
PersonPermissionsForm,
PersonsSelectionForm,
PersonTaskForm,
OrganizationForm,
PersonLookupForm,
SimpleTodoForm,
Expand Down Expand Up @@ -712,15 +710,19 @@ def person_edit(request, person_id):
person = get_object_or_404(Person, id=person_id)

person_form = PersonForm(prefix='person', instance=person)
task_form = PersonTaskForm(prefix='task', initial={'person': person})
task_form = TaskForm(
prefix='task',
initial={'person': person},
widgets={'person': HiddenInput()},
)

# Determine initial badge in PersonAwardForm
# Determine initial badge in AwardForm
try:
badge = Badge.objects.get(name=request.GET['badge'])
except (KeyError, Badge.DoesNotExist):
badge = None

# Determine initial event in PersonAwardForm
# Determine initial event in AwardForm
if 'find-training' in request.GET:
tasks = person.get_training_tasks()
if tasks.count() == 1:
Expand All @@ -730,16 +732,19 @@ def person_edit(request, person_id):
else:
event = None

# PersonAwardForm
award_form = PersonAwardForm(prefix='award', initial=dict_without_Nones(
person=person,
badge=badge,
event=event,
))
award_form = AwardForm(
prefix='award',
widgets={'person': HiddenInput()},
initial=dict_without_Nones(
person=person,
badge=badge,
event=event,
),
)

# Determine which form was sent (if any)
if request.method == 'POST' and 'award-badge' in request.POST:
award_form = PersonAwardForm(request.POST, prefix='award')
award_form = AwardForm(request.POST, prefix='award')

if award_form.is_valid():
award = award_form.save()
Expand All @@ -761,7 +766,7 @@ def person_edit(request, person_id):
extra_tags='awards')

elif request.method == 'POST' and 'task-role' in request.POST:
task_form = PersonTaskForm(request.POST, prefix='task')
task_form = TaskForm(request.POST, prefix='task')

if task_form.is_valid():
task = task_form.save()
Expand Down Expand Up @@ -1573,17 +1578,17 @@ def task_details(request, task_id):


class TaskCreate(OnlyForAdminsMixin, PermissionRequiredMixin,
AMYCreateView):
RedirectSupportMixin, AMYCreateView):
permission_required = 'workshops.add_task'
model = Task
form_class = TaskFullForm
form_class = TaskForm


class TaskUpdate(OnlyForAdminsMixin, PermissionRequiredMixin,
AMYUpdateView):
permission_required = 'workshops.change_task'
model = Task
form_class = TaskFullForm
form_class = TaskForm
pk_url_kwarg = 'task_id'


Expand Down Expand Up @@ -1662,9 +1667,9 @@ def badge_award(request, badge_name):
}

if request.method == 'GET':
form = BadgeAwardForm(initial=initial)
form = AwardForm(initial=initial, widgets={'badge': HiddenInput()})
elif request.method == 'POST':
form = BadgeAwardForm(request.POST, initial=initial)
form = AwardForm(request.POST, initial=initial)

if form.is_valid():
form.save()
Expand Down

0 comments on commit d014dd9

Please sign in to comment.