class SessionCreateHitForm(forms.Form): in_sandbox = forms.BooleanField( required=False, help_text="Do you want HIT published on MTurk sandbox?") title = forms.CharField() description = forms.CharField() keywords = forms.CharField() money_reward = forms.RealWorldCurrencyField() assignments = forms.IntegerField( label="Number of assignments", help_text="How many unique Workers do you want to work on the HIT?") minutes_allotted_per_assignment = forms.IntegerField( label="Minutes allotted per assignment", required=False, help_text=("Number of minutes, that a Worker has to " "complete the HIT after accepting it." "Leave it blank if you don't want to specify it.")) expiration_hours = forms.IntegerField( label="Hours until HIT expiration", required=False, help_text=("Number of hours after which the HIT " "is no longer available for users to accept. " "Leave it blank if you don't want to specify it.")) def __init__(self, *args, **kwargs): super(SessionCreateHitForm, self).__init__(*args, **kwargs) self.fields['assignments'].widget.attrs['readonly'] = True
class MTurkCreateHITForm(forms.Form): in_sandbox = forms.BooleanField( required=False, help_text="Do you want HIT published on MTurk sandbox?") title = forms.CharField() description = forms.CharField() keywords = forms.CharField() money_reward = forms.RealWorldCurrencyField( # it seems that if this is omitted, the step defaults to an integer, # meaninng fractional inputs are not accepted widget=widgets.RealWorldCurrencyInput(attrs={'step': 0.01}) ) assignments = forms.IntegerField( label="Number of assignments", help_text="How many unique Workers do you want to work on the HIT?") minutes_allotted_per_assignment = forms.IntegerField( label="Minutes allotted per assignment", help_text=( "Number of minutes, that a Worker has to " "complete the HIT after accepting it." )) expiration_hours = forms.FloatField( label="Hours until HIT expiration", help_text=( "Number of hours after which the HIT " "is no longer available for users to accept. " )) def __init__(self, *args, **kwargs): super(MTurkCreateHITForm, self).__init__(*args, **kwargs) self.fields['assignments'].widget.attrs['readonly'] = True
class MTurkCreateHITForm(forms.Form): use_sandbox = forms.BooleanField( required=False, label='Use MTurk Sandbox (for development and testing)', help_text=("If this box is checked, your HIT will not be published to " "the MTurk live site, but rather to the MTurk Sandbox, " "so you can test how it will look to MTurk workers.")) title = forms.CharField() description = forms.CharField() keywords = forms.CharField() money_reward = forms.RealWorldCurrencyField( # it seems that if this is omitted, the step defaults to an integer, # meaninng fractional inputs are not accepted widget=widgets._RealWorldCurrencyInput(attrs={'step': 0.01})) assignments = forms.IntegerField( label="Number of assignments", help_text="How many unique Workers do you want to work on the HIT?") minutes_allotted_per_assignment = forms.IntegerField( label="Minutes allotted per assignment", help_text=("Number of minutes, that a Worker has to " "complete the HIT after accepting it.")) expiration_hours = forms.FloatField( label="Hours until HIT expiration", help_text=("Number of hours after which the HIT " "is no longer available for users to accept. ")) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['assignments'].widget.attrs['readonly'] = True
class WidgetDemoForm(forms.Form): char = forms.CharField(required=False) text = forms.CharField(required=False, widget=forms.Textarea) radio_select = forms.ChoiceField(choices=default_choices, widget=forms.RadioSelect) radio_select_horizontal = forms.ChoiceField( choices=default_choices, widget=forms.RadioSelectHorizontal) checkbox_select = forms.MultipleChoiceField( choices=default_choices, widget=forms.CheckboxSelectMultiple) checkbox_select_horizontal = forms.MultipleChoiceField( choices=default_choices, widget=forms.CheckboxSelectMultipleHorizontal) currency = forms.CurrencyField() currency_choice = forms.CurrencyChoiceField( choices=[(m, m) for m in currency_range(0, 0.75, 0.05)]) slider = forms.IntegerField(widget=widgets.SliderInput()) unprecise_slider = forms.IntegerField(widget=widgets.SliderInput( show_value=False)) precise_slider = forms.FloatField(widget=widgets.SliderInput(attrs={ 'min': 1, 'max': 50, 'step': 0.01 }))
class AdminReportForm(forms.Form): app_name = forms.ChoiceField(choices=[], required=False) round_number = forms.IntegerField(required=False, min_value=1, initial=1) def __init__(self, *args, **kwargs): self.session = kwargs.pop('session') super().__init__(*args, **kwargs) admin_report_apps = self.session._admin_report_apps() num_rounds_list = self.session._admin_report_num_rounds_list() self.rounds_per_app = dict(zip(admin_report_apps, num_rounds_list)) app_name_choices = [] for app_name in admin_report_apps: label = '{} ({} rounds)'.format(get_app_label_from_name(app_name), self.rounds_per_app[app_name]) app_name_choices.append((app_name, label)) self.fields['app_name'].choices = app_name_choices def clean_round_number(self): app_name = self.cleaned_data['app_name'] round_number = self.cleaned_data['round_number'] if round_number and app_name: num_rounds = self.rounds_per_app[app_name] if round_number > num_rounds: self.cleaned_data['round_number'] = None raise forms.ValidationError( 'Invalid round number (max is {})'.format(num_rounds)) return round_number
class CreateSessionForm(forms.Form): num_participants = forms.IntegerField() def __init__(self, *args, **kwargs): self.session_config = kwargs.pop('session_config') for_mturk = kwargs.pop('for_mturk') super(CreateSessionForm, self).__init__(*args, **kwargs) if for_mturk: self.fields['num_participants'].label = "Number of workers" self.fields['num_participants'].help_text = ( 'Since workers can return the hit or drop out ' '"spare" participants will be created. Namely server will ' 'have %s times more participants than MTurk HIT. ' 'The number you enter in this field is number of ' 'workers required for your HIT.' % settings.MTURK_NUM_PARTICIPANTS_MULT) else: self.fields['num_participants'].label = "Number of participants" def clean_num_participants(self): lcm = get_lcm(self.session_config) num_participants = self.cleaned_data['num_participants'] if num_participants % lcm: raise forms.ValidationError( 'Number of participants must be a multiple of {}'.format(lcm)) return num_participants
class CreateSessionForm(forms.Form): session_configs = SESSION_CONFIGS_DICT.values() session_config_choices = ( # use '' instead of None. '' seems to immediately invalidate the choice, # rather than None which seems to be coerced to 'None'. [('', '-----')] + [(s['name'], s['display_name']) for s in session_configs]) session_config = forms.ChoiceField( choices=session_config_choices, required=True) num_participants = forms.IntegerField(required=False) is_mturk = forms.BooleanField( widget=widgets.HiddenInput, initial=False, required=False ) room_name = forms.CharField( initial=None, widget=widgets.HiddenInput, required=False ) def __init__(self, *args, is_mturk=False, room_name=None, **kwargs): super().__init__(*args, **kwargs) self.fields['room_name'].initial = room_name if is_mturk: self.fields['is_mturk'].initial = True self.fields['num_participants'].label = "Number of MTurk workers (assignments)" self.fields['num_participants'].help_text = ( 'Since workers can return an assignment or drop out, ' 'some "spare" participants will be created: ' f'the oTree session will have {settings.MTURK_NUM_PARTICIPANTS_MULTIPLE}' '{} times more participant objects than the number you enter here.' ) else: self.fields['num_participants'].label = "Number of participants" def clean(self): super().clean() if self.errors: return session_config_name = self.cleaned_data['session_config'] config = SESSION_CONFIGS_DICT[session_config_name] lcm = config.get_lcm() num_participants = self.cleaned_data.get('num_participants') if num_participants is None or num_participants % lcm: raise forms.ValidationError( 'Please enter a valid number of participants.' )
class CreateSessionForm(forms.Form): session_configs = SESSION_CONFIGS_DICT.values() session_config_choices = ( # use '' instead of None. '' seems to immediately invalidate the choice, # rather than None which seems to be coerced to 'None'. [('', '-----')] + [(s['name'], s['display_name']) for s in session_configs]) session_config = forms.ChoiceField( choices=session_config_choices, required=True) num_participants = forms.IntegerField() def __init__(self, *args, **kwargs): for_mturk = kwargs.pop('for_mturk') super().__init__(*args, **kwargs) if for_mturk: self.fields['num_participants'].label = "Number of MTurk workers" self.fields['num_participants'].help_text = ( 'Since workers can return the HIT or drop out, ' 'some "spare" participants will be created: ' 'the oTree session will have ' '{} times more participants than the MTurk HIT. ' 'The number you enter in this field is number of ' 'workers required for your HIT.'.format( settings.MTURK_NUM_PARTICIPANTS_MULTIPLE ) ) else: self.fields['num_participants'].label = "Number of participants" def clean_num_participants(self): session_config_name = self.cleaned_data.get('session_config') # I think when this is checked, it's possible that basic validation # for session_config_name was not done yet. # when I tested it was None # but maybe it could also be the empty string because that's what's # explicitly put above. if session_config_name: lcm = SESSION_CONFIGS_DICT[session_config_name].get_lcm() num_participants = self.cleaned_data['num_participants'] if num_participants % lcm: raise forms.ValidationError( 'Please enter a valid number of participants.' ) return num_participants
class AdminReportForm(forms.Form): app_name = forms.ChoiceField(choices=[], required=False) round_number = forms.IntegerField(required=False, min_value=1) def __init__(self, *args, session, **kwargs): self.session = session super().__init__(*args, **kwargs) admin_report_apps = self.session._admin_report_apps() num_rounds_list = self.session._admin_report_num_rounds_list() self.rounds_per_app = dict(zip(admin_report_apps, num_rounds_list)) app_name_choices = [] for app_name in admin_report_apps: label = '{} ({} rounds)'.format( get_app_label_from_name(app_name), self.rounds_per_app[app_name] ) app_name_choices.append((app_name, label)) self.fields['app_name'].choices = app_name_choices def clean(self): cleaned_data = super().clean() apps_with_admin_report = self.session._admin_report_apps() # can't use setdefault because the key will always exist even if the # fields were empty. # str default value is '', # and int default value is None if not cleaned_data['app_name']: cleaned_data['app_name'] = apps_with_admin_report[0] rounds_in_this_app = self.rounds_per_app[cleaned_data['app_name']] round_number = cleaned_data['round_number'] if not round_number or round_number > rounds_in_this_app: cleaned_data['round_number'] = rounds_in_this_app self.data = cleaned_data return cleaned_data
class CreateSessionForm(forms.Form): session_configs = SESSION_CONFIGS_DICT.values() session_config_choices = ( [('', '-----')] + [(s['name'], s['display_name']) for s in session_configs]) session_config = forms.ChoiceField( choices=session_config_choices, required=True) num_participants = forms.IntegerField() def __init__(self, *args, **kwargs): for_mturk = kwargs.pop('for_mturk') super(CreateSessionForm, self).__init__(*args, **kwargs) if for_mturk: self.fields['num_participants'].label = "Number of workers" self.fields['num_participants'].help_text = ( 'Since workers can return the hit or drop out ' '"spare" participants will be created. Namely server will ' 'have %s times more participants than MTurk HIT. ' 'The number you enter in this field is number of ' 'workers required for your HIT.' % settings.MTURK_NUM_PARTICIPANTS_MULTIPLE ) else: self.fields['num_participants'].label = "Number of participants" def clean_num_participants(self): session_config_name = self.cleaned_data.get('session_config') # We must check for an empty string in case validation is not run if session_config_name != '': lcm = SESSION_CONFIGS_DICT[session_config_name].get_lcm() num_participants = self.cleaned_data['num_participants'] if num_participants % lcm: raise forms.ValidationError( 'Please enter a valid number of participants.' ) return num_participants