class Meta: model = Member fields = [ "organization", "role", ] widgets = { "organization": ModelSelect2Widget(data_view="organization-lookup"), "role": ModelSelect2Widget(data_view="memberrole-lookup"), }
class Meta: model = MembershipTask fields = [ "person", "role", ] widgets = { "person": ModelSelect2Widget(data_view="person-lookup"), "role": ModelSelect2Widget(data_view="membershippersonrole-lookup"), }
class Meta: model = Task fields = '__all__' widgets = { 'person': ModelSelect2Widget(data_view='person-lookup', attrs=SELECT2_SIDEBAR), 'event': ModelSelect2Widget(data_view='event-lookup', attrs=SELECT2_SIDEBAR), }
class Meta: model = Sponsorship fields = '__all__' widgets = { 'organization': ModelSelect2Widget(data_view='organization-lookup', attrs=SELECT2_SIDEBAR), 'event': ModelSelect2Widget(data_view='event-lookup', attrs=SELECT2_SIDEBAR), 'contact': ModelSelect2Widget(data_view='person-lookup', attrs=SELECT2_SIDEBAR), }
class EventsSelectionForm(forms.Form): event_a = forms.ModelChoiceField( label='Event A', required=True, queryset=Event.objects.all(), widget=ModelSelect2Widget(data_view='event-lookup')) event_b = forms.ModelChoiceField( label='Event B', required=True, queryset=Event.objects.all(), widget=ModelSelect2Widget(data_view='event-lookup')) helper = BootstrapHelper(use_get_method=True, add_cancel_button=False)
class PersonsSelectionForm(forms.Form): person_a = forms.ModelChoiceField( label='Person From', required=True, queryset=Person.objects.all(), widget=ModelSelect2Widget(data_view='person-lookup')) person_b = forms.ModelChoiceField( label='Person To', required=True, queryset=Person.objects.all(), widget=ModelSelect2Widget(data_view='person-lookup')) helper = BootstrapHelper(use_get_method=True, add_cancel_button=False)
class Meta: model = Award fields = "__all__" widgets = { "person": ModelSelect2Widget(data_view="person-lookup", attrs=SELECT2_SIDEBAR), "event": ModelSelect2Widget(data_view="event-lookup", attrs=SELECT2_SIDEBAR), "awarded_by": ModelSelect2Widget(data_view="admin-lookup", attrs=SELECT2_SIDEBAR), }
class Meta: model = Sponsorship fields = "__all__" widgets = { "organization": ModelSelect2Widget( data_view="organization-lookup", attrs=SELECT2_SIDEBAR ), "event": ModelSelect2Widget( data_view="event-lookup", attrs=SELECT2_SIDEBAR ), "contact": ModelSelect2Widget( data_view="person-lookup", attrs=SELECT2_SIDEBAR ), }
class BadgeAwardsFilter(AMYFilterSet): awarded_after = django_filters.DateFilter(field_name="awarded", lookup_expr="gte") awarded_before = django_filters.DateFilter(field_name="awarded", lookup_expr="lte") event = django_filters.ModelChoiceFilter( queryset=Event.objects.all(), label="Event", widget=ModelSelect2Widget( data_view="event-lookup", attrs=SELECT2_SIDEBAR, ), ) order_by = django_filters.OrderingFilter( fields=( "awarded", "person__family", ), field_labels={ "awarded": "Awarded date", "person__family": "Person", }, ) class Meta: model = Award fields = ( "awarded_after", "awarded_before", "event", )
class TaskFilter(AMYFilterSet): event = django_filters.ModelChoiceFilter( queryset=Event.objects.all(), label="Event", widget=ModelSelect2Widget( data_view="event-lookup", attrs=SELECT2_SIDEBAR, ), ) order_by = django_filters.OrderingFilter( fields=( ("event__slug", "event"), ("person__family", "person"), ("role", "role"), ), field_labels={ "event__slug": "Event", "person__family": "Person", "role": "Role", }, ) class Meta: model = Task fields = [ "event", # can't filter on person because person's name contains 3 fields: # person.personal, person.middle, person.family # 'person', "role", ]
class TaskFilter(AMYFilterSet): event = django_filters.ModelChoiceFilter( queryset=Event.objects.all(), label='Event', widget=ModelSelect2Widget( data_view='event-lookup', attrs=SELECT2_SIDEBAR, ), ) order_by = django_filters.OrderingFilter(fields=( ('event__slug', 'event'), ('person__family', 'person'), ('role', 'role'), ), field_labels={ 'event__slug': 'Event', 'person__family': 'Person', 'role': 'Role', }) class Meta: model = Task fields = [ 'event', # can't filter on person because person's name contains 3 fields: # person.personal, person.middle, person.family # 'person', 'role', ]
class BadgeAwardsFilter(AMYFilterSet): awarded_after = django_filters.DateFilter(field_name='awarded', lookup_expr='gte') awarded_before = django_filters.DateFilter(field_name='awarded', lookup_expr='lte') event = django_filters.ModelChoiceFilter( queryset=Event.objects.all(), label='Event', widget=ModelSelect2Widget( data_view='event-lookup', attrs=SELECT2_SIDEBAR, ), ) order_by = django_filters.OrderingFilter(fields=( 'awarded', 'person__family', ), field_labels={ 'awarded': 'Awarded date', 'person__family': 'Person', }) class Meta: model = Award fields = ( 'awarded_after', 'awarded_before', 'event', )
class TaskForm(WidgetOverrideMixin, forms.ModelForm): helper = BootstrapHelper(add_cancel_button=False) SEAT_MEMBERSHIP_HELP_TEXT = ( '{}<br><b>Hint:</b> you can use input format YYYY-MM-DD to display ' 'memberships available on that date.'.format( Task._meta.get_field('seat_membership').help_text)) seat_membership = forms.ModelChoiceField( label=Task._meta.get_field('seat_membership').verbose_name, help_text=SEAT_MEMBERSHIP_HELP_TEXT, required=False, queryset=Membership.objects.all(), widget=ModelSelect2Widget( data_view='membership-lookup', attrs=SELECT2_SIDEBAR, )) class Meta: model = Task fields = '__all__' widgets = { 'person': ModelSelect2Widget(data_view='person-lookup', attrs=SELECT2_SIDEBAR), 'event': ModelSelect2Widget(data_view='event-lookup', attrs=SELECT2_SIDEBAR), }
class EventLookupForm(forms.Form): event = forms.ModelChoiceField( label='Event', required=True, queryset=Event.objects.all(), widget=ModelSelect2Widget(data_view='event-lookup')) helper = BootstrapHelper(add_cancel_button=False)
class TraineeFilter(AMYFilterSet): search = django_filters.CharFilter( method=filter_trainees_by_trainee_name_or_email, label='Name or Email') all_persons = django_filters.BooleanFilter( label='Include all people, not only trainees', method=filter_all_persons, widget=widgets.CheckboxInput) homework = django_filters.BooleanFilter( label='Only trainees with unevaluated homework', widget=widgets.CheckboxInput, method=filter_trainees_by_unevaluated_homework_presence, ) training_request = django_filters.BooleanFilter( label='Is training request present?', method=filter_trainees_by_training_request_presence, ) is_instructor = django_filters.ChoiceFilter( label='Is Instructor?', method=filter_trainees_by_instructor_status, choices=[ ('', 'Unknown'), ('all', 'All instructor badges'), ('any', 'Any instructor badge '), ('swc', 'SWC instructor'), ('dc', 'DC instructor'), ('lc', 'LC instructor'), ('eligible', 'No, but eligible to be certified'), ('no', 'No instructor badge'), ]) training = django_filters.ModelChoiceFilter( queryset=Event.objects.ttt(), method=filter_trainees_by_training, label='Training', widget=ModelSelect2Widget( data_view='ttt-event-lookup', attrs=SELECT2_SIDEBAR, ), ) order_by = NamesOrderingFilter(fields=( 'last_login', 'email', ), ) class Meta: model = Person fields = [ 'search', 'all_persons', 'homework', 'is_instructor', 'training', ]
class PersonLookupForm(forms.Form): person = forms.ModelChoiceField( label="Person", required=True, queryset=Person.objects.all(), widget=ModelSelect2Widget(data_view="person-lookup"), ) helper = BootstrapHelper(use_get_method=True, add_cancel_button=False)
class Meta: model = MembershipTask fields = [ # The membership field is required for uniqueness validation. We're making # it hidden from user to not confuse them, and to discourage from changing # field's value. The downside of this approach is that a) user can provide # different ID if they try hard enough, and b) tests get a little bit # harder as additional value has to be provided. "membership", "person", "role", ] widgets = { "membership": forms.HiddenInput, "person": ModelSelect2Widget(data_view="person-lookup"), "role": ModelSelect2Widget(data_view="membershippersonrole-lookup"), }
class Meta: model = Task fields = [ "event", "person", "role", "title", "url", "seat_membership", "seat_open_training", ] widgets = { "person": ModelSelect2Widget(data_view="person-lookup", attrs=SELECT2_SIDEBAR), "event": ModelSelect2Widget(data_view="event-lookup", attrs=SELECT2_SIDEBAR), }
class BulkAddTrainingProgressForm(forms.ModelForm): event = forms.ModelChoiceField( label="Training", required=False, queryset=Event.objects.filter(tags__name="TTT"), widget=ModelSelect2Widget(data_view="ttt-event-lookup", attrs=SELECT2_SIDEBAR), ) trainees = forms.ModelMultipleChoiceField(queryset=Person.objects.all()) helper = BootstrapHelper( additional_form_class="training-progress", submit_label="Add", form_tag=False, add_cancel_button=False, ) helper.layout = Layout( # no 'trainees' -- you should take care of generating it manually in # the template where this form is used "requirement", "state", "event", "url", "notes", ) class Meta: model = TrainingProgress fields = [ # no 'trainees' "requirement", "state", "event", "url", "notes", ] widgets = { "state": RadioSelect, "notes": TextInput, } def clean(self): cleaned_data = super().clean() trainees = cleaned_data.get("trainees") # check if all trainees have at least one training task for trainee in trainees: training_tasks = trainee.get_training_tasks() if not training_tasks: raise ValidationError("It's not possible to add training " "progress to a trainee without any " "training task.")
class SWCEventRequestNoCaptchaForm(PrivacyConsentMixin, forms.ModelForm): workshop_type = forms.CharField(initial='swc', widget=forms.HiddenInput()) understand_admin_fee = forms.BooleanField( required=True, initial=False, label='I understand the Software Carpentry Foundation\'s ' 'administration fee.', help_text='<a href="http://software-carpentry.org/blog/2015/07/changes' '-to-admin-fee.html" target="_blank" rel="noreferrer">' 'Look up administration fees</a>.', ) language = forms.ModelChoiceField( label='Language', required=False, queryset=Language.objects.all(), widget=ModelSelect2Widget(data_view='language-lookup') ) helper = BootstrapHelper(wider_labels=True, add_cancel_button=False, duplicate_buttons_on_top=True) class Meta: model = EventRequest exclude = ('created_at', 'last_updated_at', 'assigned_to', 'data_types', 'data_types_other', 'attendee_data_analysis_level', 'fee_waiver_request', ) widgets = { 'event': Select2Widget, 'approx_attendees': forms.RadioSelect(), 'attendee_domains': CheckboxSelectMultipleWithOthers( 'attendee_domains_other'), 'attendee_academic_levels': forms.CheckboxSelectMultiple(), 'attendee_computing_levels': forms.CheckboxSelectMultiple(), 'travel_reimbursement': RadioSelectWithOther( 'travel_reimbursement_other'), 'admin_fee_payment': forms.RadioSelect(), 'country': Select2Widget, } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # set up a layout object for the helper self.helper.layout = self.helper.build_default_layout(self) # set up RadioSelectWithOther widget so that it can display additional # field inline self['attendee_domains'].field.widget.other_field = \ self['attendee_domains_other'] self['travel_reimbursement'].field.widget.other_field = \ self['travel_reimbursement_other'] # remove that additional field self.helper.layout.fields.remove('attendee_domains_other') self.helper.layout.fields.remove('travel_reimbursement_other')
class AdminLookupForm(forms.Form): person = forms.ModelChoiceField( label="Administrator", required=True, queryset=Person.objects.all(), widget=ModelSelect2Widget( data_view="admin-lookup", attrs=SELECT2_SIDEBAR, ), ) helper = BootstrapHelper(add_cancel_button=False)
class PersonForm(forms.ModelForm): airport = forms.ModelChoiceField( label='Airport', required=False, queryset=Airport.objects.all(), widget=ModelSelect2Widget(data_view='airport-lookup')) languages = forms.ModelMultipleChoiceField( label='Languages', required=False, queryset=Language.objects.all(), widget=ModelSelect2MultipleWidget(data_view='language-lookup')) helper = BootstrapHelper(add_cancel_button=False, duplicate_buttons_on_top=True) class Meta: model = Person # don't display the 'password', 'user_permissions', # 'groups' or 'is_superuser' fields # + reorder fields fields = [ 'username', 'personal', 'middle', 'family', 'may_contact', 'publish_profile', 'lesson_publication_consent', 'data_privacy_agreement', 'email', 'gender', 'country', 'airport', 'affiliation', 'github', 'twitter', 'url', 'occupation', 'orcid', 'user_notes', 'lessons', 'domains', 'languages', ] widgets = { 'country': Select2Widget, }
class TaskForm(WidgetOverrideMixin, forms.ModelForm): SEAT_MEMBERSHIP_HELP_TEXT = ( "{}<br><b>Hint:</b> you can use input format YYYY-MM-DD to display " "memberships available on that date.".format( Task._meta.get_field("seat_membership").help_text)) seat_membership = forms.ModelChoiceField( label=Task._meta.get_field("seat_membership").verbose_name, help_text=SEAT_MEMBERSHIP_HELP_TEXT, required=False, queryset=Membership.objects.all(), widget=ModelSelect2Widget( data_view="membership-lookup", attrs=SELECT2_SIDEBAR, ), ) class Meta: model = Task fields = [ "event", "person", "role", "title", "url", "seat_membership", "seat_open_training", ] widgets = { "person": ModelSelect2Widget(data_view="person-lookup", attrs=SELECT2_SIDEBAR), "event": ModelSelect2Widget(data_view="event-lookup", attrs=SELECT2_SIDEBAR), } def __init__(self, *args, **kwargs): form_tag = kwargs.pop("form_tag", True) super().__init__(*args, **kwargs) self.helper = BootstrapHelper(add_cancel_button=False, form_tag=form_tag)
class MembershipForm(forms.ModelForm): helper = BootstrapHelper(add_cancel_button=False) organization = forms.ModelChoiceField( label='Organization', required=True, queryset=Organization.objects.all(), widget=ModelSelect2Widget(data_view='organization-lookup')) class Meta: model = Membership fields = [ 'organization', 'variant', 'agreement_start', 'agreement_end', 'contribution_type', 'workshops_without_admin_fee_per_agreement', 'self_organized_workshops_per_agreement', 'seats_instructor_training', 'additional_instructor_training_seats', ]
class TrainingProgressForm(forms.ModelForm): trainee = forms.ModelChoiceField( label="Trainee", required=True, queryset=Person.objects.all(), widget=ModelSelect2Widget(data_view="person-lookup"), ) evaluated_by = forms.ModelChoiceField( label="Evaluated by", required=False, queryset=Person.objects.all(), widget=ModelSelect2Widget(data_view="admin-lookup"), ) event = forms.ModelChoiceField( label="Event", required=False, queryset=Event.objects.all(), widget=ModelSelect2Widget(data_view="event-lookup", attrs=SELECT2_SIDEBAR), ) # helper used in edit view helper = BootstrapHelper( duplicate_buttons_on_top=True, submit_label="Update", add_delete_button=True, additional_form_class="training-progress", add_cancel_button=False, ) # helper used in create view create_helper = BootstrapHelper( duplicate_buttons_on_top=True, submit_label="Add", additional_form_class="training-progress", add_cancel_button=False, ) class Meta: model = TrainingProgress fields = [ "trainee", "evaluated_by", "requirement", "state", "discarded", "event", "url", "notes", ] widgets = { "state": RadioSelect, } def clean(self): cleaned_data = super().clean() trainee = cleaned_data.get("trainee") # check if trainee has at least one training task training_tasks = trainee.get_training_tasks() if not training_tasks: raise ValidationError("It's not possible to add training progress " "to a trainee without any training task.")
class MembershipCreateForm(MembershipForm): comment = MarkdownxFormField( label="Comment", help_text= "This will be added to comments after the membership is created.", widget=forms.Textarea, required=False, ) helper = BootstrapHelper(add_cancel_button=True) main_organization = forms.ModelChoiceField( Organization.objects.all(), label="Main organisation", required=True, widget=ModelSelect2Widget(data_view="organization-lookup"), help_text= "Select main organisation (e.g. Signatory in case of consortium).", ) class Meta(MembershipForm.Meta): fields = MembershipForm.Meta.fields.copy() fields.insert(0, "main_organization") fields.remove("extensions") fields.append("comment") class Media: js = ("membership_create.js", ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["consortium"].help_text += ( "<br>If you select this option, you'll be taken to the next screen to " "select organisations engaged in consortium. You must create the " "organisation (<a href='{}'>here</a>) before applying it to this " "membership.").format(reverse("organization_add")) # set up a layout object for the helper self.helper.layout = self.helper.build_default_layout(self) # add warning alert for dates falling within next 2-3 months STANDARD_PACKAGES_PREPOPULATION_WARNING = ( "<b>Workshops without admin fee per agreement</b> and " "<b>Public instructor training seats</b> were adjusted according to " "standard membership packages.") pos_index = self.helper.layout.fields.index("variant") self.helper.layout.insert( pos_index + 1, Div( Div( HTML(STANDARD_PACKAGES_PREPOPULATION_WARNING), css_class="alert alert-warning offset-lg-2 col-lg-8 col-12", ), id="standard_packages_prepopulation_warning", css_class="form-group row d-none", ), ) def save(self, *args, **kwargs): res = super().save(*args, **kwargs) create_comment_signal.send( sender=self.__class__, content_object=res, comment=self.cleaned_data["comment"], timestamp=None, ) return res
class WorkshopStaffForm(forms.Form): """Represent instructor matching form.""" latitude = forms.FloatField(label="Latitude", min_value=-90.0, max_value=90.0, required=False) longitude = forms.FloatField(label="Longitude", min_value=-180.0, max_value=180.0, required=False) airport = forms.ModelChoiceField( label="Airport", required=False, queryset=Airport.objects.all(), widget=ModelSelect2Widget(data_view="airport-lookup", attrs=SELECT2_SIDEBAR), ) languages = forms.ModelMultipleChoiceField( label="Languages", required=False, queryset=Language.objects.all(), widget=ModelSelect2MultipleWidget( data_view="language-lookup", attrs=SELECT2_SIDEBAR, ), ) country = forms.MultipleChoiceField( choices=list(Countries()), required=False, widget=Select2MultipleWidget, ) continent = forms.ChoiceField( choices=continent_list, required=False, widget=Select2Widget, ) lessons = forms.ModelMultipleChoiceField( queryset=Lesson.objects.all(), widget=SelectMultiple(), required=False, ) badges = forms.ModelMultipleChoiceField( queryset=Badge.objects.instructor_badges(), widget=CheckboxSelectMultiple(), required=False, ) is_trainer = forms.BooleanField(required=False, label="Has Trainer badge") GENDER_CHOICES = ((None, "---------"), ) + Person.GENDER_CHOICES gender = forms.ChoiceField(choices=GENDER_CHOICES, required=False) was_helper = forms.BooleanField(required=False, label="Was helper at least once before") was_organizer = forms.BooleanField( required=False, label="Was organizer at least once before") is_in_progress_trainee = forms.BooleanField( required=False, label="Is an in-progress instructor trainee") def __init__(self, *args, **kwargs): """Build form layout dynamically.""" super().__init__(*args, **kwargs) self.helper = FormHelper(self) self.helper.form_method = "get" self.helper.layout = Layout( Div( Div( HTML('<h5 class="card-title">Location</h5>'), "airport", HTML("<hr>"), "country", HTML("<hr>"), "continent", HTML("<hr>"), "latitude", "longitude", css_class="card-body", ), css_class="card", ), "badges", "is_trainer", HTML("<hr>"), "was_helper", "was_organizer", "is_in_progress_trainee", "languages", "gender", "lessons", Submit("", "Submit"), ) def clean(self): cleaned_data = super().clean() lat = bool(cleaned_data.get("latitude")) lng = bool(cleaned_data.get("longitude")) airport = bool(cleaned_data.get("airport")) country = bool(cleaned_data.get("country")) latlng = lat and lng # if searching by coordinates, then there must be both lat & lng # present if lat ^ lng: raise ValidationError( "Must specify both latitude and longitude if searching by " "coordinates") # User must search by airport, or country, or coordinates, or none # of them. Sum of boolean elements must be equal 0 (if general search) # or 1 (if searching by airport OR country OR lat/lng). if sum([airport, country, latlng]) not in [0, 1]: raise ValidationError( "Must specify an airport OR a country, OR use coordinates, OR " "none of them.") return cleaned_data
class EventForm(forms.ModelForm): host = forms.ModelChoiceField( label="Host", required=True, help_text=Event._meta.get_field("host").help_text, queryset=Organization.objects.all(), widget=ModelSelect2Widget(data_view="organization-lookup"), ) administrator = forms.ModelChoiceField( label="Administrator", required=True, help_text=Event._meta.get_field("administrator").help_text, queryset=Organization.objects.administrators(), widget=ModelSelect2Widget(data_view="administrator-org-lookup"), ) assigned_to = forms.ModelChoiceField( label="Assigned to", required=False, queryset=Person.objects.all(), widget=ModelSelect2Widget(data_view="admin-lookup"), ) language = forms.ModelChoiceField( label="Language", required=False, queryset=Language.objects.all(), widget=ModelSelect2Widget(data_view="language-lookup"), ) country = CountryField().formfield( required=False, help_text=Event._meta.get_field("country").help_text, widget=Select2Widget, ) comment = MarkdownxFormField( label="Comment", help_text="Any content in here will be added to comments after this " "event is saved.", widget=forms.Textarea, required=False, ) helper = BootstrapHelper(add_cancel_button=False, duplicate_buttons_on_top=True) class Meta: model = Event fields = [ "slug", "completed", "start", "end", "host", "administrator", "assigned_to", "tags", "url", "language", "reg_key", "venue", "manual_attendance", "contact", "country", "address", "latitude", "longitude", "open_TTT_applications", "curricula", "lessons", "public_status", "comment", ] widgets = { "manual_attendance": TextInput, "latitude": TextInput, "longitude": TextInput, "tags": SelectMultiple(attrs={"size": Tag.ITEMS_VISIBLE_IN_SELECT_WIDGET}), # "tags": CheckboxSelectMultiple(), "curricula": CheckboxSelectMultiple(), "lessons": CheckboxSelectMultiple(), "contact": Select2TagWidget, } class Media: # thanks to this, {{ form.media }} in the template will generate # a <link href=""> (for CSS files) or <script src=""> (for JS files) js = ( "date_yyyymmdd.js", "edit_from_url.js", "online_country.js", ) def __init__(self, *args, **kwargs): show_lessons = kwargs.pop("show_lessons", False) add_comment = kwargs.pop("add_comment", True) super().__init__(*args, **kwargs) self.helper.layout = Layout( Field("slug", placeholder="YYYY-MM-DD-location"), "completed", Field("start", placeholder="YYYY-MM-DD"), Field("end", placeholder="YYYY-MM-DD"), "host", "public_status", "administrator", "assigned_to", "tags", "open_TTT_applications", "curricula", "url", "language", "reg_key", "manual_attendance", "contact", Div( Div(HTML("Location details"), css_class="card-header"), Div( "country", "venue", "address", "latitude", "longitude", css_class="card-body", ), css_class="card mb-2", ), ) # if we want to show lessons, we need to alter existing layout # otherwise we should remove the field so it doesn't break validation if show_lessons: self.helper.layout.insert( # insert AFTER the curricula self.helper.layout.fields.index("curricula") + 1, "lessons", ) else: del self.fields["lessons"] if add_comment: self.helper.layout.append("comment") else: del self.fields["comment"] def clean_slug(self): # Ensure slug is in "YYYY-MM-DD-location" format data = self.cleaned_data["slug"] match = re.match(r"(\d{4}|x{4})-(\d{2}|x{2})-(\d{2}|x{2})-.+", data) if not match: raise ValidationError('Slug must be in "YYYY-MM-DD-location"' ' format, where "YYYY", "MM", "DD" can' ' be unspecified (ie. "xx").') return data def clean_end(self): """Ensure end >= start.""" start = self.cleaned_data["start"] end = self.cleaned_data["end"] if start and end and end < start: raise ValidationError("Must not be earlier than start date.") return end def clean_open_TTT_applications(self): """Ensure there's a TTT tag applied to the event, if the `open_TTT_applications` is True.""" open_TTT_applications = self.cleaned_data["open_TTT_applications"] tags = self.cleaned_data.get("tags", None) error_msg = "You cannot open applications on a non-TTT event." if open_TTT_applications and tags: # find TTT tag TTT_tag = False for tag in tags: if tag.name == "TTT": TTT_tag = True break if not TTT_tag: raise ValidationError(error_msg) elif open_TTT_applications: raise ValidationError(error_msg) return open_TTT_applications def clean_curricula(self): """Validate tags when some curricula are selected.""" curricula = self.cleaned_data["curricula"] tags = self.cleaned_data["tags"] try: expected_tags = [] for c in curricula: if c.active and c.carpentry: expected_tags.append(c.carpentry) elif c.active and c.mix_match: expected_tags.append("Circuits") except (ValueError, TypeError): expected_tags = [] for tag in expected_tags: if not tags.filter(name=tag): raise forms.ValidationError( "You must add tags corresponding to these curricula.") return curricula def clean_manual_attendance(self): """Regression: #1608 - fix 500 server error when field is cleared.""" manual_attendance = self.cleaned_data["manual_attendance"] or 0 return manual_attendance def save(self, *args, **kwargs): res = super().save(*args, **kwargs) comment = self.cleaned_data.get("comment") if comment: create_comment_signal.send( sender=self.__class__, content_object=res, comment=comment, timestamp=None, ) return res
class PersonForm(forms.ModelForm): airport = forms.ModelChoiceField( label="Airport", required=False, queryset=Airport.objects.all(), widget=ModelSelect2Widget(data_view="airport-lookup"), ) languages = forms.ModelMultipleChoiceField( label="Languages", required=False, queryset=Language.objects.all(), widget=ModelSelect2MultipleWidget(data_view="language-lookup"), ) helper = BootstrapHelper(add_cancel_button=False, duplicate_buttons_on_top=True) class Meta: model = Person # don't display the 'password', 'user_permissions', # 'groups' or 'is_superuser' fields # + reorder fields fields = [ "username", "personal", "middle", "family", "may_contact", "publish_profile", "lesson_publication_consent", "data_privacy_agreement", "email", "secondary_email", "gender", "gender_other", "country", "airport", "affiliation", "github", "twitter", "url", "occupation", "orcid", "user_notes", "lessons", "domains", "languages", ] widgets = { "country": Select2Widget, "gender": RadioSelectWithOther("gender_other"), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # set up a layout object for the helper self.helper.layout = self.helper.build_default_layout(self) # set up `*WithOther` widgets so that they can display additional # fields inline self["gender"].field.widget.other_field = self["gender_other"] # remove additional fields self.helper.layout.fields.remove("gender_other") def clean(self): super().clean() errors = dict() # 1: require "other gender" field if "other" was selected in # "gender" field gender = self.cleaned_data.get("gender", "") gender_other = self.cleaned_data.get("gender_other", "") if gender == GenderMixin.OTHER and not gender_other: errors["gender"] = ValidationError("This field is required.") elif gender != GenderMixin.OTHER and gender_other: errors["gender"] = ValidationError( 'If you entered data in "Other" field, please select that ' "option.") # raise errors if any present if errors: raise ValidationError(errors)
class TraineeFilter(AMYFilterSet): search = django_filters.CharFilter( method=filter_trainees_by_trainee_name_or_email, label="Name or Email" ) all_persons = django_filters.BooleanFilter( label="Include all people, not only trainees", method=filter_all_persons, widget=widgets.CheckboxInput, ) homework = django_filters.BooleanFilter( label="Only trainees with unevaluated homework", widget=widgets.CheckboxInput, method=filter_trainees_by_unevaluated_homework_presence, ) training_request = django_filters.BooleanFilter( label="Is training request present?", method=filter_trainees_by_training_request_presence, ) is_instructor = django_filters.ChoiceFilter( label="Is Instructor?", method=filter_trainees_by_instructor_status, choices=[ ("", "Unknown"), ("all", "All instructor badges"), ("any", "Any instructor badge "), ("swc", "SWC instructor"), ("dc", "DC instructor"), ("lc", "LC instructor"), ("eligible", "No, but eligible to be certified"), ("no", "No instructor badge"), ], ) training = django_filters.ModelChoiceFilter( queryset=Event.objects.ttt(), method=filter_trainees_by_training, label="Training", widget=ModelSelect2Widget( data_view="ttt-event-lookup", attrs=SELECT2_SIDEBAR, ), ) order_by = NamesOrderingFilter( fields=( "last_login", "email", ), ) class Meta: model = Person fields = [ "search", "all_persons", "homework", "is_instructor", "training", ]