Skip to content

Commit

Permalink
Fix requested_depts_ids
Browse files Browse the repository at this point in the history
There were two issues with this field:
1. It was spelled as requested_dept_ids (dept vs depts)
2. It's a special property on the Attendee class, which means it's not included in all_checkgroups, which means it wasn't being preprocessed correctly.

This fixes both of those. It also slightly refactors how we preprocess data by moving it into the process function rather than the init function. This does mean the form gets processed twice -- once on init and again after initializing the dynamic chocies -- but I think we don't have much choice there.
  • Loading branch information
kitsuta committed Aug 31, 2023
1 parent 03c93f6 commit d0e9481
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 21 deletions.
2 changes: 1 addition & 1 deletion tests/locust/dealerreg/locustfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ def preregister(self):
"form_list": "PreregOtherInfo"
}
if is_staffing:
additional_info["requested_dept_ids"] = random.sample(departments, random.randrange(len(departments)+1))
additional_info["requested_depts_ids"] = random.sample(departments, random.randrange(len(departments)+1))
additional_info["interests"] = random.sample(interests, random.randrange(len(interests)+1))
if random.randrange(2):
additional_info["requested_accessibility_services"] = "1"
Expand Down
2 changes: 1 addition & 1 deletion tests/locust/prereg/locustfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def preregister(self):
"csrf_token": csrf_token,
"staffing": "1",
"cellphone": cellphone,
"requested_dept_ids": "252431566",
"requested_depts_ids": "252431566",
"requested_accessibility_services": "1",
"form_list": "PreregOtherInfo"
}
Expand Down
32 changes: 18 additions & 14 deletions uber/forms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
from collections import defaultdict, OrderedDict
from importlib import import_module
from markupsafe import Markup
from wtforms import Form, StringField, SelectField, IntegerField, BooleanField, validators
from wtforms import Form, StringField, SelectField, SelectMultipleField, IntegerField, BooleanField, validators
import wtforms.widgets.core as wtforms_widgets
from wtforms.validators import Optional, ValidationError, StopValidation
from wtforms.utils import unset_value
from pockets.autolog import log
from uber.config import c
from uber.forms.widgets import *
Expand Down Expand Up @@ -63,7 +64,7 @@ def load_forms(params, model, module, form_list, prefix_dict={}, get_optional=Tr
else:
alias_dict[aliased_field] = alias_val

loaded_form = form_cls(params, model, checkboxes_present=checkboxes_present, prefix=prefix_dict.get(cls, ''), data=alias_dict)
loaded_form = form_cls(params, model, prefix=prefix_dict.get(cls, ''))
optional_fields = loaded_form.get_optional_fields(model) if get_optional else []

for name, field in loaded_form._fields.items():
Expand All @@ -74,11 +75,13 @@ def load_forms(params, model, module, form_list, prefix_dict={}, get_optional=Tr
override_validators = get_override_attr(loaded_form, name, '_validators', field)
if override_validators:
field.validators = override_validators

# Refresh any choices for fields in "dynamic_choices_fields" so we can have up-to-date choices for select fields
if name in loaded_form.dynamic_choices_fields.keys():
field.choices = loaded_form.dynamic_choices_fields[name]()

loaded_form.process(params, model, checkboxes_present=checkboxes_present, data=alias_dict)

form_label = re.sub(r'(?<!^)(?=[A-Z])', '_', cls).lower()
if truncate_prefix and form_label.startswith(truncate_prefix + '_'):
form_label = form_label[(len(truncate_prefix) + 1):]
Expand Down Expand Up @@ -164,11 +167,8 @@ def form_mixin(cls, form):
setattr(target, name, getattr(form, name))
return target

def __init__(self, formdata=None, obj=None, prefix='', data=None, meta=None, checkboxes_present=True, **kwargs):
meta_obj = self._wtforms_meta()
if meta is not None and isinstance(meta, dict):
meta_obj.update_values(meta)
super(Form, self).__init__(self._unbound_fields, meta=meta_obj, prefix=prefix)
def process(self, formdata=None, obj=None, data=None, extra_filters=None, checkboxes_present=True, **kwargs):
formdata = self.meta.wrap_formdata(self, formdata)

# Special form data preprocessing!
#
Expand All @@ -177,19 +177,23 @@ def __init__(self, formdata=None, obj=None, prefix='', data=None, meta=None, che
# in which case we set it to false
#
# We also convert our MultiChoice value (a string) into the list of strings that WTForms expects

for name, field in self._fields.items():
field_in_obj = hasattr(obj, name)
field_in_formdata = name in formdata
use_blank_formdata = cherrypy.request.method == 'POST' and checkboxes_present
if isinstance(field, BooleanField) and not field_in_formdata and field_in_obj:
if cherrypy.request.method == 'POST' and checkboxes_present:
formdata[name] = False
formdata[name] = False if use_blank_formdata else getattr(obj, name)
elif (isinstance(field, SelectMultipleField) or hasattr(obj, 'all_checkgroups') and name in obj.all_checkgroups
) and not field_in_formdata:
if use_blank_formdata:
formdata[name] = []
elif field_in_obj and isinstance(getattr(obj, name), str):
formdata[name] = getattr(obj, name).split(',')
else:
formdata[name] = getattr(obj, name)
elif hasattr(obj, 'all_checkgroups') and not field_in_formdata and field_in_obj and \
name in obj.all_checkgroups and isinstance(getattr(obj, name), str):
formdata[name] = getattr(obj, name).split(',')

super().__init__(formdata, obj, prefix, data, meta, **kwargs)
super().process(formdata, obj, data, extra_filters, **kwargs)

@property
def field_list(self):
Expand Down
6 changes: 3 additions & 3 deletions uber/forms/attendee.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,14 +239,14 @@ def out_of_badge_type(form, field):


class OtherInfo(MagForm):
dynamic_choices_fields = {'requested_dept_ids': lambda: [(v[0], v[1]) for v in c.PUBLIC_DEPARTMENT_OPTS_WITH_DESC] if len(c.PUBLIC_DEPARTMENT_OPTS_WITH_DESC) > 1 else c.JOB_INTEREST_OPTS}
dynamic_choices_fields = {'requested_depts_ids': lambda: [(v[0], v[1]) for v in c.PUBLIC_DEPARTMENT_OPTS_WITH_DESC] if len(c.PUBLIC_DEPARTMENT_OPTS_WITH_DESC) > 1 else c.JOB_INTEREST_OPTS}

placeholder = BooleanField(widget=HiddenInput())
staffing = BooleanField('I am interested in volunteering!', widget=SwitchInput(), description=popup_link(c.VOLUNTEER_PERKS_URL, "What do I get for volunteering?"))
requested_dept_ids = SelectMultipleField('Where do you want to help?', widget=MultiCheckbox()) # TODO: Show attendees department descriptions
requested_depts_ids = SelectMultipleField('Where do you want to help?', widget=MultiCheckbox()) # TODO: Show attendees department descriptions
requested_accessibility_services = BooleanField(f'I would like to be contacted by the {c.EVENT_NAME} Accessibility Services department prior to the event and I understand my contact information will be shared with Accessibility Services for this purpose.', widget=SwitchInput())
interests = SelectMultipleField('What interests you?', choices=c.INTEREST_OPTS, coerce=int, validators=[validators.Optional()], widget=MultiCheckbox())

def get_non_admin_locked_fields(self, attendee):
locked_fields = []

Expand Down
1 change: 1 addition & 0 deletions uber/site_sections/preregistration.py
Original file line number Diff line number Diff line change
Expand Up @@ -1467,6 +1467,7 @@ def confirm(self, session, message='', return_to='confirm', undoing_extra='', **

session.add(attendee)
session.commit()

if placeholder:
attendee.confirmed = localized_now()
message = 'Your registration has been confirmed'
Expand Down
4 changes: 2 additions & 2 deletions uber/templates/forms/attendee/other_info.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
{% endif %}
<div class="row g-sm-3">
<div class="col-12">{{ form_macros.toggle_checkbox(other_info.staffing,
[other_info.requested_dept_ids, other_info.cellphone] if include_cellphone else [other_info.requested_dept_ids], toggle_required=True, help_text=staffing_message) }}</div>
[other_info.requested_depts_ids, other_info.cellphone] if include_cellphone else [other_info.requested_depts_ids], toggle_required=True, help_text=staffing_message) }}</div>
</div>

{% if include_cellphone %}
Expand All @@ -44,7 +44,7 @@

{% if c.JOB_INTEREST_OPTS or c.PUBLIC_DEPARTMENT_OPTS_WITH_DESC|length > 1 %}
<div class="row g-sm-3">
<div class="col-12">{{ form_macros.form_input(other_info.requested_dept_ids) }}</div>
<div class="col-12">{{ form_macros.form_input(other_info.requested_depts_ids) }}</div>
</div>
{% endif %}
{% endblock %}
Expand Down

0 comments on commit d0e9481

Please sign in to comment.