-
Notifications
You must be signed in to change notification settings - Fork 56
/
forms.py
582 lines (511 loc) · 28.8 KB
/
forms.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
from django import forms
from django.conf import settings
from django.forms import ModelForm
from django.template.defaultfilters import filesizeformat
from django.utils import timezone
from app.mixins import OverwriteOnlyModelFormMixin, BootstrapFormMixin
from app.utils import validate_url
from applications import models
import requests
def set_field_html_name(cls, new_name):
"""
This creates wrapper around the normal widget rendering,
allowing for a custom field name (new_name).
"""
old_render = cls.widget.render
def _widget_render_wrapper(name, value, attrs=None):
return old_render(new_name, value, attrs)
cls.widget.render = _widget_render_wrapper
class _BaseApplicationForm(OverwriteOnlyModelFormMixin, BootstrapFormMixin, ModelForm):
phone_number = forms.CharField(required=False, widget=forms.TextInput(
attrs={'class': 'form-control', 'placeholder': '+#########'}))
under_age = forms.TypedChoiceField(
required=True,
label='How old are you?',
initial=False,
coerce=lambda x: x == 'True',
choices=((False, '18 or over'), (True, 'Under 18')),
widget=forms.RadioSelect
)
code_conduct = forms.BooleanField(required=False,
label='I have read and accept the '
'<a href="%s" target="_blank">%s Code of Conduct</a>' % (
getattr(settings, 'CODE_CONDUCT_LINK', '/code_conduct'),
settings.HACKATHON_NAME), )
def clean_code_conduct(self):
cc = self.cleaned_data.get('code_conduct', False)
# Check that if it's the first submission hackers checks code of conduct checkbox
# self.instance.pk is None if there's no Application existing before
# https://stackoverflow.com/questions/9704067/test-if-django-modelform-has-instance
if not cc and not self.instance.pk:
raise forms.ValidationError(
"To attend %s you must abide by our code of conduct" % settings.HACKATHON_NAME)
return cc
def clean_other_diet(self):
data = self.cleaned_data['other_diet']
diet = self.cleaned_data['diet']
if diet == 'Others' and not data:
raise forms.ValidationError("Please tell us your specific dietary requirements")
return data
def clean_other_gender(self):
data = self.cleaned_data['other_gender']
gender = self.cleaned_data['gender']
if gender == models.GENDER_OTHER and not data:
raise forms.ValidationError("Please enter this field or select 'Prefer not to answer'")
return data
def clean_origin(self):
origin = self.cleaned_data['origin']
if origin == "Others":
origin_verified = origin
else:
response = requests.get('https://api.teleport.org/api/cities/', params={'search': origin})
data = response.json()['_embedded']['city:search-results']
if not data:
raise forms.ValidationError("Please select one of the dropdown options or write 'Others'")
else:
origin_verified = data[0]['matching_full_name']
return origin_verified
def __getitem__(self, name):
item = super(_BaseApplicationForm, self).__getitem__(name)
item.field.disabled = not self.instance.can_be_edit()
return item
class Meta:
exclude = ['user', 'uuid', 'invited_by', 'submission_date', 'status_update_date', 'status', ]
class _HackerMentorVolunteerApplicationForm(OverwriteOnlyModelFormMixin, ModelForm):
first_timer = forms.TypedChoiceField(
required=True,
label='Will %s be your first hackathon?' % settings.HACKATHON_NAME,
coerce=lambda x: x == 'True',
choices=((False, 'No'), (True, 'Yes')),
widget=forms.RadioSelect
)
university = forms.CharField(required=True,
label='What university do you study at?',
help_text='Current or most recent school you attended.',
widget=forms.TextInput(
attrs={'class': 'typeahead-schools', 'autocomplete': 'off'}))
degree = forms.CharField(required=True, label='What\'s your major/degree?',
help_text='Current or most recent degree you\'ve received',
widget=forms.TextInput(
attrs={'class': 'typeahead-degrees', 'autocomplete': 'off'}))
class _HackerMentorApplicationForm(OverwriteOnlyModelFormMixin, ModelForm):
github = forms.CharField(required=False, widget=forms.TextInput(
attrs={'class': 'form-control',
'placeholder': 'https://github.com/johnBiene'}))
devpost = forms.CharField(required=False, widget=forms.TextInput(
attrs={'class': 'form-control',
'placeholder': 'https://devpost.com/JohnBiene'}))
linkedin = forms.CharField(required=False, widget=forms.TextInput(
attrs={'class': 'form-control',
'placeholder': 'https://www.linkedin.com/in/john_biene'}))
site = forms.CharField(required=False, widget=forms.TextInput(
attrs={'class': 'form-control', 'placeholder': 'https://biene.space'}))
def clean_resume(self):
resume = self.cleaned_data['resume']
size = getattr(resume, '_size', 0)
if size > settings.MAX_UPLOAD_SIZE:
raise forms.ValidationError("Please keep resume size under %s. Current filesize %s" % (
filesizeformat(settings.MAX_UPLOAD_SIZE), filesizeformat(size)))
return resume
def clean_github(self):
data = self.cleaned_data['github']
validate_url(data, 'github.com')
return data
def clean_devpost(self):
data = self.cleaned_data['devpost']
validate_url(data, 'devpost.com')
return data
def clean_linkedin(self):
data = self.cleaned_data['linkedin']
validate_url(data, 'linkedin.com')
return data
def clean_projects(self):
data = self.cleaned_data['projects']
first_timer = self.cleaned_data['first_timer']
if not first_timer and not data:
raise forms.ValidationError("Please fill this in order for us to know you a bit better")
return data
class HackerApplicationForm(_BaseApplicationForm, _HackerMentorApplicationForm, _HackerMentorVolunteerApplicationForm):
reimb = forms.TypedChoiceField(
required=False,
label='Do you need a travel reimbursement to attend?',
coerce=lambda x: x == 'True',
choices=((False, 'No'), (True, 'Yes')),
initial=False,
widget=forms.RadioSelect
)
bootstrap_field_info = {
'Personal Info': {
'fields': [{'name': 'university', 'space': 12}, {'name': 'degree', 'space': 12},
{'name': 'graduation_year', 'space': 12}, {'name': 'gender', 'space': 12},
{'name': 'other_gender', 'space': 12}, {'name': 'phone_number', 'space': 12},
{'name': 'tshirt_size', 'space': 12}, {'name': 'diet', 'space': 12},
{'name': 'other_diet', 'space': 12}, {'name': 'under_age', 'space': 12},
{'name': 'lennyface', 'space': 12}, ],
'description': 'Hey there, before we begin we would like to know a little more about you.'
},
'Hackathons?': {
'fields': [{'name': 'description', 'space': 12}, {'name': 'first_timer', 'space': 12},
{'name': 'projects', 'space': 12}, ]
},
'Show us what you\'ve built': {
'fields': [{'name': 'github', 'space': 12}, {'name': 'devpost', 'space': 12},
{'name': 'linkedin', 'space': 12}, {'name': 'site', 'space': 12},
{'name': 'resume', 'space': 12}, {'name': 'description', 'space': 12}, ],
'description': 'Some of our sponsors may use this information for recruitment purposes,'
'so please include as much as you can.'
}
}
def clean_reimb_amount(self):
data = self.cleaned_data['reimb_amount']
reimb = self.cleaned_data.get('reimb', False)
if reimb and not data:
raise forms.ValidationError("To apply for reimbursement please set a valid amount")
deadline = getattr(settings, 'REIMBURSEMENT_DEADLINE', False)
if data and deadline and deadline <= timezone.now():
raise forms.ValidationError("Reimbursement applications are now closed. Trying to hack us?")
return data
def clean_reimb(self):
reimb = self.cleaned_data.get('reimb', False)
deadline = getattr(settings, 'REIMBURSEMENT_DEADLINE', False)
if reimb and deadline and deadline <= timezone.now():
raise forms.ValidationError("Reimbursement applications are now closed. Trying to hack us?")
return reimb
def get_bootstrap_field_info(self):
fields = super().get_bootstrap_field_info()
deadline = getattr(settings, 'REIMBURSEMENT_DEADLINE', False)
r_enabled = getattr(settings, 'REIMBURSEMENT_ENABLED', False)
if r_enabled and deadline and deadline <= timezone.now() and not self.instance.pk:
fields['Traveling'] = {'fields': [{'name': 'origin', 'space': 12}, ],
'description': 'Reimbursement applications are now closed. '
'Sorry for the inconvenience.',
}
elif self.instance.pk and r_enabled:
fields['Traveling'] = {'fields': [{'name': 'origin', 'space': 12}, ],
'description': 'If you applied for reimbursement, check out the Travel tab. '
'Email us at %s for any change needed on reimbursements.' %
settings.HACKATHON_CONTACT_EMAIL,
}
elif not r_enabled:
fields['Traveling'] = {'fields': [{'name': 'origin', 'space': 12}, ], }
else:
fields['Traveling'] = {'fields': [{'name': 'origin', 'space': 12}, {'name': 'reimb', 'space': 12},
{'name': 'reimb_amount', 'space': 12}, ], }
# Fields that we only need the first time the hacker fills the application
# https://stackoverflow.com/questions/9704067/test-if-django-modelform-has-instance
if not self.instance.pk:
fields['Code of Conduct'] = {'fields': [{'name': 'code_conduct', 'space': 12}, ], }
return fields
class Meta(_BaseApplicationForm.Meta):
model = models.HackerApplication
extensions = getattr(settings, 'SUPPORTED_RESUME_EXTENSIONS', None)
help_texts = {
'gender': 'This is for demographic purposes.',
'graduation_year': 'What year have you graduated on or when will '
'you graduate',
'degree': 'What\'s your major/degree?',
'other_diet': 'Please fill here in your dietary requirements. We want to make sure we have food for you!',
'lennyface': 'tip: you can chose from here <a href="http://textsmili.es/" target="_blank">'
' http://textsmili.es/</a>',
'projects': 'You can talk about about past hackathons, personal projects, awards etc. '
'(we love links) Show us your passion! :D',
'reimb_amount': 'We try our best to cover costs for all hackers, but our budget is limited',
'resume': 'Accepted file formats: %s' % (', '.join(extensions) if extensions else 'Any'),
'origin': "Please select one of the dropdown options or write 'Others'"
}
widgets = {
'origin': forms.TextInput(attrs={'autocomplete': 'off'}),
'description': forms.Textarea(attrs={'rows': 3, 'cols': 40}),
'projects': forms.Textarea(attrs={'rows': 3, 'cols': 40}),
'graduation_year': forms.RadioSelect(),
}
labels = {
'gender': 'What gender do you identify as?',
'other_gender': 'Self-describe',
'graduation_year': 'What year will you graduate?',
'tshirt_size': 'What\'s your t-shirt size?',
'diet': 'Dietary requirements',
'lennyface': 'Describe yourself in one "lenny face"?',
'origin': 'Where are you joining us from?',
'description': 'Why are you excited about %s?' % settings.HACKATHON_NAME,
'projects': 'What projects have you worked on?',
'resume': 'Upload your resume',
'reimb_amount': 'How much money (%s) would you need to afford traveling to %s?' % (
getattr(settings, 'CURRENCY', '$'), settings.HACKATHON_NAME),
}
class VolunteerApplicationForm(_BaseApplicationForm, _HackerMentorVolunteerApplicationForm):
first_time_volunteer = forms.TypedChoiceField(
required=True,
label='Have you volunteered at %s before?' % settings.HACKATHON_NAME,
coerce=lambda x: x == 'True',
choices=((False, 'No'), (True, 'Yes')),
widget=forms.RadioSelect
)
which_hack = forms.MultipleChoiceField(
required=False,
label='Which %s editions have you volunteered in?' % settings.HACKATHON_NAME,
widget=forms.CheckboxSelectMultiple,
choices=models.PREVIOUS_HACKS
)
bootstrap_field_info = {
'Personal Info': {
'fields': [{'name': 'origin', 'space': 12}, {'name': 'university', 'space': 12},
{'name': 'degree', 'space': 12}, {'name': 'graduation_year', 'space': 12},
{'name': 'gender', 'space': 12}, {'name': 'other_gender', 'space': 12},
{'name': 'phone_number', 'space': 12}, {'name': 'tshirt_size', 'space': 12},
{'name': 'diet', 'space': 12}, {'name': 'other_diet', 'space': 12},
{'name': 'under_age', 'space': 12}, {'name': 'lennyface', 'space': 12}, ],
'description': 'Hey there, before we begin we would like to know a little more about you.'
},
'Volunteer Skills': {
'fields': [{'name': 'first_timer', 'space': 12}, {'name': 'first_time_volunteer', 'space': 12},
{'name': 'which_hack', 'space': 12}, {'name': 'attendance', 'space': 12},
{'name': 'english_level', 'space': 12}, {'name': 'quality', 'space': 12},
{'name': 'weakness', 'space': 12}, {'name': 'cool_skill', 'space': 12},
{'name': 'fav_movie', 'space': 12}, {'name': 'friends', 'space': 12},
],
}
}
def clean(self):
data = self.cleaned_data['which_hack']
volunteer = self.cleaned_data['first_time_volunteer']
if volunteer and not data:
self.add_error('which_hack', "Choose the hackathons you volunteered")
return super(VolunteerApplicationForm, self).clean()
def volunteer(self):
return True
def clean_reimb_amount(self):
data = self.cleaned_data['reimb_amount']
reimb = self.cleaned_data.get('reimb', False)
if reimb and not data:
raise forms.ValidationError("To apply for reimbursement please set a valid amount")
deadline = getattr(settings, 'REIMBURSEMENT_DEADLINE', False)
if data and deadline and deadline <= timezone.now():
raise forms.ValidationError("Reimbursement applications are now closed. Trying to hack us?")
return data
def clean_reimb(self):
reimb = self.cleaned_data.get('reimb', False)
deadline = getattr(settings, 'REIMBURSEMENT_DEADLINE', False)
if reimb and deadline and deadline <= timezone.now():
raise forms.ValidationError("Reimbursement applications are now closed. Trying to hack us?")
return reimb
def get_bootstrap_field_info(self):
fields = super().get_bootstrap_field_info()
# Fields that we only need the first time the hacker fills the application
# https://stackoverflow.com/questions/9704067/test-if-django-modelform-has-instance
if not self.instance.pk:
fields['Code of Conduct'] = {'fields': [{'name': 'code_conduct', 'space': 12}, ], }
return fields
class Meta(_BaseApplicationForm.Meta):
model = models.VolunteerApplication
help_texts = {
'gender': 'This is for demographic purposes.',
'graduation_year': 'What year have you graduated on or when will '
'you graduate',
'degree': 'What\'s your major/degree?',
'other_diet': 'Please fill here in your dietary requirements. We want to make sure we have food for you!',
'lennyface': 'tip: you can chose from here <a href="http://textsmili.es/" target="_blank">'
' http://textsmili.es/</a>',
'attendance': "It will be a great experience to enjoy from beginning to end with lots of things to do, "
"but it is ok if you can't make it the whole weekend!",
'english_level': "No English level needed to volunteer, we just want to check which of you would be"
" comfortable doing tasks that require communication in English!",
'fav_movie': 'e.g.: Interstellar, Pirates of the Caribbean, Mulan, Twilight, etc.',
'cool_skill': 'e.g: can lift 300kg deadweight, have web development skills, can read minds, '
'time traveler...',
'friends': '*Remember that you all have to apply separately'
}
widgets = {
'origin': forms.TextInput(attrs={'autocomplete': 'off'}),
'graduation_year': forms.RadioSelect(),
'english_level': forms.RadioSelect(),
'friends': forms.Textarea(attrs={'rows': 2, 'cols': 40}),
'weakness': forms.Textarea(attrs={'rows': 2, 'cols': 40}),
'quality': forms.Textarea(attrs={'rows': 2, 'cols': 40}),
}
labels = {
'gender': 'What gender do you identify as?',
'other_gender': 'Self-describe',
'graduation_year': 'What year will you graduate?',
'tshirt_size': 'What\'s your t-shirt size?',
'diet': 'Dietary requirements',
'lennyface': 'Describe yourself in one "lenny face"?',
'origin': 'Where are you joining us from?',
'which_hack': 'Which %s editions have you volunteered in?' % settings.HACKATHON_NAME,
'attendance': 'Will you be attending HackUPC for the whole event?',
'english_level': 'How much confident are you about talking in English?',
'quality': 'Tell us a quality of yourself :)',
'weakness': 'Now a weakness :(',
'cool_skill': 'Do you have any cool skills we should know about?',
'fav_movie': 'Which is your favorite movie?',
'friends': 'If you are applying with some of your friends, please mention their names'
}
class MentorApplicationForm(_BaseApplicationForm, _HackerMentorApplicationForm, _HackerMentorVolunteerApplicationForm):
first_time_mentor = forms.TypedChoiceField(
required=True,
label='Have you mentored at %s before?' % settings.HACKATHON_NAME,
coerce=lambda x: x == 'True',
choices=((False, 'No'), (True, 'Yes')),
widget=forms.RadioSelect)
study_work = forms.TypedChoiceField(
required=True,
label='Are you studying or working?',
coerce=lambda x: x == 'True',
choices=((False, 'Working'), (True, 'Studying')),
widget=forms.RadioSelect)
company = forms.CharField(required=False,
help_text='Current or most recent company you attended.',
label='Where are you working at?')
university = forms.CharField(required=False,
label='What university do you study at?',
help_text='Current or most recent school you attended.',
widget=forms.TextInput(
attrs={'class': 'typeahead-schools', 'autocomplete': 'off'}))
degree = forms.CharField(required=False, label='What\'s your major/degree?',
help_text='Current or most recent degree you\'ve received',
widget=forms.TextInput(
attrs={'class': 'typeahead-degrees', 'autocomplete': 'off'}))
bootstrap_field_info = {
'Personal Info': {
'fields': [{'name': 'origin', 'space': 12}, {'name': 'study_work', 'space': 12},
{'name': 'company', 'space': 12}, {'name': 'university', 'space': 12},
{'name': 'degree', 'space': 12}, {'name': 'graduation_year', 'space': 12},
{'name': 'gender', 'space': 12}, {'name': 'other_gender', 'space': 12},
{'name': 'phone_number', 'space': 12}, {'name': 'tshirt_size', 'space': 12},
{'name': 'diet', 'space': 12}, {'name': 'other_diet', 'space': 12},
{'name': 'under_age', 'space': 12}, {'name': 'lennyface', 'space': 12}, ],
'description': 'Hey there, before we begin we would like to know a little more about you.'
},
'Mentor Skills': {
'fields': [{'name': 'why_mentor', 'space': 12}, {'name': 'first_timer', 'space': 12},
{'name': 'first_time_mentor', 'space': 12}, {'name': 'which_hack', 'space': 12},
{'name': 'participated', 'space': 12}, {'name': 'attendance', 'space': 12},
{'name': 'english_level', 'space': 12}, {'name': 'fluent', 'space': 12},
{'name': 'experience', 'space': 12}, ],
},
'Show us what you\'ve built': {
'fields': [{'name': 'github', 'space': 12}, {'name': 'devpost', 'space': 12},
{'name': 'linkedin', 'space': 12}, {'name': 'site', 'space': 12},
{'name': 'resume', 'space': 12}, ]
}
}
def mentor(self):
return True
def get_bootstrap_field_info(self):
fields = super().get_bootstrap_field_info()
if not self.instance.pk:
fields['Code of Conduct'] = {'fields': [{'name': 'code_conduct', 'space': 12}, ], }
return super(MentorApplicationForm, self).fieldsets
def clean(self):
data = self.cleaned_data['which_hack']
mentor = self.cleaned_data['first_time_mentor']
if mentor and not data:
self.add_error('which_hack', "Choose the hackathons you mentored")
study = self.cleaned_data['study_work']
if study:
if not self.cleaned_data['university']:
self.add_error('university', 'Type your university, please')
if not self.cleaned_data['degree']:
self.add_error('degree', 'Type your degree, please')
if not self.cleaned_data['graduation_year']:
self.add_error('graduation_year', 'Choose your graduation year, please')
else:
if not self.cleaned_data['company']:
self.add_error('company', 'Type your company, please')
return super(MentorApplicationForm, self).clean()
class Meta(_BaseApplicationForm.Meta):
model = models.MentorApplication
extensions = getattr(settings, 'SUPPORTED_RESUME_EXTENSIONS', None)
help_texts = {
'gender': 'This is for demographic purposes.',
'graduation_year': 'What year have you graduated on or when will '
'you graduate',
'degree': 'What\'s your major/degree?',
'other_diet': 'Please fill here in your dietary requirements. We want to make sure we have food for you!',
'lennyface': 'tip: you can chose from here <a href="http://textsmili.es/" target="_blank">'
' http://textsmili.es/</a>',
'participated': 'You can talk about about past hackathons or any other events. ',
'resume': 'Accepted file formats: %s' % (', '.join(extensions) if extensions else 'Any'),
}
widgets = {
'origin': forms.TextInput(attrs={'autocomplete': 'off'}),
'participated': forms.Textarea(attrs={'rows': 3, 'cols': 40}),
'graduation_year': forms.RadioSelect(),
'english_level': forms.RadioSelect(),
'fluent': forms.Textarea(attrs={'rows': 2, 'cols': 40}),
'experience': forms.Textarea(attrs={'rows': 2, 'cols': 40}),
'why_mentor': forms.Textarea(attrs={'rows': 2, 'cols': 40}),
}
labels = {
'gender': 'What gender do you identify as?',
'other_gender': 'Self-describe',
'graduation_year': 'What year will you graduate?',
'tshirt_size': 'What\'s your t-shirt size?',
'diet': 'Dietary requirements',
'lennyface': 'Describe yourself in one "lenny face"?',
'origin': 'Where are you joining us from?',
'description': 'Why are you excited about %s?' % settings.HACKATHON_NAME,
'participated': 'Have you participated as mentor in other hackathons or tech events?',
'resume': 'Upload your resume',
'why_mentor': 'Why do you want to participate as mentor?',
'which_hack': 'Which editions have you mentored?',
'attendance': 'Will you be attending HackUPC for the whole event?',
'english_level': 'How much confident are you about talking in English?',
'fluent': 'What program languages are you fluent on?',
'experience': 'Which program languages have you experience on?'
}
class SponsorForm(OverwriteOnlyModelFormMixin, BootstrapFormMixin, ModelForm):
phone_number = forms.CharField(required=False, widget=forms.TextInput(
attrs={'class': 'form-control', 'placeholder': '+#########'}))
code_conduct = forms.BooleanField(required=False,
label='I have read and accept the '
'<a href="%s" target="_blank">%s Code of Conduct</a>' % (
getattr(settings, 'CODE_CONDUCT_LINK', '/code_conduct'),
settings.HACKATHON_NAME), )
bootstrap_field_info = {
'Personal Info': {
'fields': [{'name': 'name', 'space': 12}, {'name': 'phone_number', 'space': 12},
{'name': 'tshirt_size', 'space': 12}, {'name': 'diet', 'space': 12},
{'name': 'other_diet', 'space': 12}, {'name': 'position', 'space': 12},
{'name': 'attendance', 'space': 12}, ],
'description': 'Hey there, before we begin we would like to know a little more about you.'
},
}
def clean_code_conduct(self):
cc = self.cleaned_data.get('code_conduct', False)
# Check that if it's the first submission hackers checks code of conduct checkbox
# self.instance.pk is None if there's no Application existing before
# https://stackoverflow.com/questions/9704067/test-if-django-modelform-has-instance
if not cc and not self.instance.pk:
raise forms.ValidationError(
"To attend %s you must abide by our code of conduct" % settings.HACKATHON_NAME)
return cc
def clean_other_diet(self):
data = self.cleaned_data['other_diet']
diet = self.cleaned_data['diet']
if diet == 'Others' and not data:
raise forms.ValidationError("Please tell us your specific dietary requirements")
return data
def clean_other_gender(self):
data = self.cleaned_data['other_gender']
gender = self.cleaned_data['gender']
if gender == models.GENDER_OTHER and not data:
raise forms.ValidationError("Please enter this field or select 'Prefer not to answer'")
return data
def fieldsets(self):
fields = super().get_bootstrap_field_info()
if not self.instance.pk:
fields['Code of Conduct'] = {'fields': [{'name': 'code_conduct', 'space': 12}, ], }
return super(SponsorForm, self).fieldsets
class Meta:
model = models.SponsorApplication
help_texts = {
'other_diet': 'Please fill here in your dietary requirements. We want to make sure we have food for you!',
}
labels = {
'tshirt_size': 'What\'s your t-shirt size?',
'diet': 'Dietary requirements',
'attendance': 'What availability will you have during the event?',
'position': 'What is your job position?',
}
exclude = ['user', 'uuid', 'submission_date', 'status_update_date', 'status', ]