Example #1
0
    def get_form(self, form_class):

        stage_configurations = self.stage.get_queryset_configurations()

        form = form_class(**self.get_form_kwargs())

        used_arg_names = []

        # We want to inject fields into the form for the configurations they've marked as prompt
        for config in stage_configurations:
            if config.task_argument and config.task_name != self.task_name:
                continue

            if not config.prompt_me_for_input:
                if config.task_argument:
                    used_arg_names.append(config.key)
                continue

            str_config_key = 'configuration_value_for_{}'.format(config.key)

            if config.data_type == config.BOOLEAN_TYPE:
                field = BooleanField(widget=Select(choices=((False, 'False'), (True, 'True'))))
                field.coerce=lambda x: x == 'True',
            elif config.data_type == config.NUMBER_TYPE:
                field = FloatField()
            else:
                field = CharField()

                if config.sensitive_value:
                    field.widget = PasswordInput()

                if config.task_argument:
                    used_arg_names.append(config.key)
                    field.label = 'Argument value for ' + config.key

            field.initial = config.value

            form.fields[str_config_key] = field
            form.helper.layout.fields.insert(len(form.helper.layout.fields)-1, str_config_key)

        task_details = get_task_details(self.stage.project, self.task_name)

        for arg in task_details[2]:
            if isinstance(arg, tuple):
                name, default = arg
            else:
                name, default = arg, None

            if name in used_arg_names:
                continue

            str_config_key = 'configuration_value_for_{}'.format(name)

            field = CharField(label='Argument value for ' + name, initial=default)

            form.fields[str_config_key] = field
            form.helper.layout.fields.insert(len(form.helper.layout.fields)-1, str_config_key)

        return form
Example #2
0
 def test_booleanfield_clean_2(self):
     f = BooleanField(required=False)
     self.assertIs(f.clean(''), False)
     self.assertIs(f.clean(None), False)
     self.assertIs(f.clean(True), True)
     self.assertIs(f.clean(False), False)
     self.assertIs(f.clean(1), True)
     self.assertIs(f.clean(0), False)
     self.assertIs(f.clean('1'), True)
     self.assertIs(f.clean('0'), False)
     self.assertIs(f.clean('Django rocks'), True)
     self.assertIs(f.clean('False'), False)
     self.assertIs(f.clean('false'), False)
     self.assertIs(f.clean('FaLsE'), False)
Example #3
0
 def test_booleanfield_changed(self):
     f = BooleanField()
     self.assertFalse(f.has_changed(None, None))
     self.assertFalse(f.has_changed(None, ''))
     self.assertFalse(f.has_changed('', None))
     self.assertFalse(f.has_changed('', ''))
     self.assertTrue(f.has_changed(False, 'on'))
     self.assertFalse(f.has_changed(True, 'on'))
     self.assertTrue(f.has_changed(True, ''))
     # Initial value may have mutated to a string due to show_hidden_initial (#19537)
     self.assertTrue(f.has_changed('False', 'on'))
Example #4
0
    def get_form(self, form_class):

        stage_configurations = self.stage.get_queryset_configurations(prompt_me_for_input=True)

        form = form_class(**self.get_form_kwargs())

        # We want to inject fields into the form for the configurations they've marked as prompt
        for config in stage_configurations:
            if config.task_argument and config.task_name != self.task_name:
                continue

            str_config_key = 'configuration_value_for_{}'.format(config.key)

            if config.data_type == config.BOOLEAN_TYPE:
                field = BooleanField(widget=Select(choices=((False, 'False'), (True, 'True'))))
                field.coerce=lambda x: x == 'True',
            elif config.data_type == config.NUMBER_TYPE:
                field = FloatField()
            else:
                field = CharField()

                if config.sensitive_value:
                    field.widget = PasswordInput

                if config.task_argument:
                    field.label = 'Argument value for ' + config.key

            form.fields[str_config_key] = field
            form.helper.layout.fields.insert(len(form.helper.layout.fields)-1, str_config_key)

        return form
class EnrollmentForm(ModelForm):
    """
    Campo para permitir facturar automaticamente el examen medico de YMCA sin tener que crear una
    compra al finalizar el agregado de la suscripcion.
    """
    add_ymca_medical_exam = BooleanField(
        required=False,
        label=_("Debit medical exam"),
        help_text=
        _("Select this to automatically add a purchase for the YMCA medical exam"
          ))

    def __init__(self, *args, **kwargs):
        super(EnrollmentForm, self).__init__(*args, **kwargs)
        if 'service' in self.fields:
            self.fields['service'].queryset = Service.active.all()

    class Meta:
        model = Enrollment
        fields = ['student', 'service', 'billable', 'add_ymca_medical_exam']
        widgets = {
            'student': MemberSearchWidget,
        }

    class Media:
        js = ('enrollment-ymca-autohide.js', )

    def save(self, commit=True):
        instance = super(EnrollmentForm, self).save(commit=False)

        if instance.id is None:
            instance.save(add_ymca_medical_exam=self.
                          cleaned_data['add_ymca_medical_exam'])
        else:
            instance.save()

        return instance
Example #6
0
class ScoreForm(ModelForm):
    save_player = BooleanField(
        label=_("Save the selected player for next score registration"),
        required=False)

    def clean(self):
        if self.cleaned_data["game"] and self.cleaned_data[
                "score"] and self.cleaned_data["player"]:
            tournament = Tournament.objects.get(is_active=True)
            score = get_object_or_None(Score,
                                       game=self.cleaned_data["game"],
                                       score=self.cleaned_data["score"],
                                       player=self.cleaned_data["player"],
                                       tournament=tournament)
            if score:
                raise ValidationError(
                    _("This score has already been registered"))

    def clean_score(self):
        if self.cleaned_data["score"]:
            numbers = ''.join(c for c in self.cleaned_data["score"]
                              if c.isdigit())
            if numbers:
                return numbers

        return self.cleaned_data["score"]

    def save(self, commit=True):
        score = super().save(commit=False)
        if commit:
            score.tournament = Tournament.objects.get(is_active=True)
            score.save()
        return score

    class Meta:
        model = Score
        fields = ["game", "score", "player"]
Example #7
0
class EventForm(ModelForm):
    class Meta:
        model = Event
        fields = ('name', 'date', 'review_state', 'location', 'tour',
                  'bookstore', 'meta')

    class Media:
        js = ('palanaeum/js/third_party/modernizr.js',
              'palanaeum/js/modernize_forms.js')

    date = DateField(widget=DateInput(attrs={'type': 'date'}))
    # Selected tags will be added by JavaScript
    tags = CharField(label=_('Tags'),
                     required=False,
                     widget=SelectMultiple(attrs={
                         'class': 'tag-selector',
                         'data-tags': "true"
                     }))
    update_entry_dates = BooleanField(
        label=_('Update entry dates'),
        required=False,
        help_text=_("Will modify the dates of "
                    "entries which didn't have different date set."))

    def __init__(self, *args, **kwargs):
        super(EventForm, self).__init__(*args, **kwargs)
        self.original_date = self.instance.date

    def save(self, commit=True):
        if self.cleaned_data['update_entry_dates']:
            Entry.objects.filter(
                event=self.instance,
                date=self.original_date).update(date=self.cleaned_data['date'])
        super(EventForm, self).save()
        self.instance.update_tags(self.cleaned_data['tags'].replace("'",
                                                                    '')[1:-1])
        return self.instance
Example #8
0
class UserProfileForm(forms.ModelForm):
	# the widget gets rid of <a href=
	photo = FileField(widget=forms.FileInput)
	birthday = DateField(widget=DateWidget)  # input_formats=settings.DATE_INPUT_FORMATS
	suggestions = BooleanField(widget=BooleanWidget)
	logs = BooleanField(widget=BooleanWidget)
	embedded_youtube =BooleanField(widget=BooleanWidget)
	highlight_code = BooleanField(widget=BooleanWidget, help_text="```console.log('Highlight code like this')```")
	incoming_file_call_sound = BooleanField(widget=BooleanWidget)
	message_sound = BooleanField(widget=BooleanWidget)
	online_change_sound = BooleanField(widget=BooleanWidget)
	password = forms.CharField(widget=PasswordWidget)
	THEME_CHOICES = (
		('color-reg', 'Modern'),
		('color-lor', 'Simple'),
		('color-white', 'Light(Beta)'),
	)
	theme = ChoiceField(required=True, choices=THEME_CHOICES)
	GENDER_CHOICES = (
		(1, 'Male'),
		(2, 'Female'),
		(0, 'Alien'),
	)
	# implement here to set required = remove ---- choice in favor of alien
	sex = ChoiceField(required=True, choices=GENDER_CHOICES)

	class Meta:  # pylint: disable=C1001
		model = UserProfile
		fields = ('username', 'name', 'city', 'surname', 'email', 'birthday', 'contacts', 'sex', 'photo', 'suggestions', 'logs', 'embedded_youtube', 'highlight_code', 'message_sound', 'incoming_file_call_sound', 'online_change_sound', 'theme', 'password')

	def __init__(self, *args, **kwargs):
		"""
		Creates the entire form for changing UserProfile.
		"""
		super(UserProfileForm, self).__init__(*args, **kwargs)

		for key in self.fields:
			if key != 'username':
				self.fields[key].required = False
Example #9
0
class JobForm(ModelForm):
    job_name = forms.CharField(label='Job Name', max_length=255, required=True)
    # city = forms.CharField(label='City', max_length=128, required=True)

    job = ChoiceField([])

    state = ChoiceField([], required=True)
    open = BooleanField(required=False)

    class Meta:
        model = EmployerJob
        fields = ['id', 'city', 'custom_email_body', 'open', 'job_description']

    def __init__(self, *args, **kwargs):
        super(JobForm, self).__init__(*args, **kwargs)
        for field_name, field in self.fields.items():
            if field_name == 'job' or field_name == 'state':
                field.widget.attrs['class'] = 'browser-default'

        self.fields['state'].choices = make_choice_set_for_state_codes()

    def limit_jobs_to_employer(self, employer_id):
        self.fields['job'].choices = make_job_structure_for_dropdown(
            False, employer_id)
Example #10
0
class ImageForm(ModelForm):
    '''Generic custom form for models containing an ImageField.'''

    # extra field not present in model, used for deletion of previously uploaded image
    delete_image = BooleanField(required=False)

    #  override form clean() method to execute custom validation on 'image' field.
    def clean(self):

        # invoke superclass cleaning method
        super(ImageForm, self).clean()

        # check image size on upload
        image = self.cleaned_data.get("image")
        delete_image = self.cleaned_data.get("delete_image")
        try:
            if image is not None and delete_image is False and image.size > MAX_IMAGE_SIZE:
                self._errors["image"] = self.error_class(
                    ["Image size exceeds the maximum allowed."])
        except OSError as e:
            # image not existing on disk
            print e

        return self.cleaned_data
Example #11
0
class OrgBeneficiaryOwnerForm(Form):
    id = IntegerField(required=False, widget=HiddenInput())
    fio = CharField(required=False,
                    max_length=512,
                    widget=TextInput(attrs={'class': 'form-control input-sm'}))
    legal_address = CharField(required=False,
                              max_length=512,
                              widget=TextInput(
                                  attrs={
                                      'class': 'form-control input-sm req',
                                      'placeholder': 'Обязательно к заполнению'
                                  }))
    fact_address = CharField(required=False,
                             max_length=512,
                             widget=TextInput(
                                 attrs={
                                     'class': 'form-control input-sm req',
                                     'placeholder': 'Обязательно к заполнению'
                                 }))
    post_address = CharField(
        required=False,
        max_length=512,
        widget=TextInput(attrs={'class': 'form-control input-sm'}))
    inn_or_snils = CharField(
        required=False,
        max_length=512,
        widget=TextInput(attrs={'class': 'form-control input-sm'}))
    on_belong_to_pub_persons_info = CharField(
        required=False,
        max_length=512,
        widget=TextInput(attrs={'class': 'form-control input-sm'}))
    DELETE = BooleanField(required=False,
                          widget=CheckboxInput(attrs={'class': 'hidden'}))

    class Media(object):
        js = formset_media_js
Example #12
0
class LegacySubscribedMixin(ModelForm):
    subscribed_lfi = BooleanField(
        label="Recevoir les lettres d'information",
        help_text="Vous recevrez les lettres de la France insoumise, notamment : les lettres d'information, les"
        " appels à volontaires, les annonces d'émissions ou d'événements...",
        required=False,
    )

    def __init__(self, *args, instance=None, **kwargs):
        super().__init__(
            *args, instance=instance, **kwargs,
        )

        self.fields["subscribed_lfi"].initial = (
            instance is not None and Person.NEWSLETTER_LFI in instance.newsletters
        )

    def save(self, commit=True):
        subscribed_lfi = self.cleaned_data.get("subscribed_lfi", False)
        if subscribed_lfi and Person.NEWSLETTER_LFI not in self.instance.newsletters:
            self.instance.newsletters.append(Person.NEWSLETTER_LFI)
        elif not subscribed_lfi and Person.NEWSLETTER_LFI in self.instance.newsletters:
            self.instance.newsletters.remove(Person.NEWSLETTER_LFI)
        return super().save(commit)
Example #13
0
class ArticleForm(forms.Form):
    title = CharField(max_length=120)
    #Required has to be False, because i did not find a way that i could edit an article without uplouding an image again.
    header_image = ImageField(required=False)

    is_read = BooleanField(required=False, initial=False)
    # is_read = TypedChoiceField(
    #choices=((True, 'Yes'), (False, 'No')),
    # widget=CheckBox,
    #coerce=lambda x: x == 'True',
    #initial="False",
    # required=False
    #)
    text = CharField()
    category = ChoiceField(choices=CATEGORIES, required=False)

    class Meta:
        #The two below has something to do with assigning who the author of the article is
        model = Article
        exclude = ('user', )

    #Check if the things that is written in the form are valid
    def clean(self):
        return self.cleaned_data
Example #14
0
class ContactUpdateModelForm(FormCleanContactNumber, ModelForm):
    has_confirmed = BooleanField(initial=False, required=False)
    need_to_confirm = False

    class Meta:
        model = default_contact_model
        fields = default_contact_fields

    def __init__(self, *args, **kwargs):
        if 'request' in kwargs.keys():
            self.request = kwargs.pop('request')

        super().__init__(*args, **kwargs)

    def clean(self):
        # if name exists make user confirm
        cleaned_data = super().clean()
        name = cleaned_data.get('name', '')
        name_initial = self.initial['name']
        has_confirmed = cleaned_data['has_confirmed']
        self.need_to_confirm = False

        contacts = self.Meta.model.objects.filter(name__iexact=name)
        has_changed = name_initial.lower() != name.lower()
        if contacts.exists() and has_changed:
            if not has_confirmed:
                msg = 'A contact with name "{}"\
                    already exists. Please confirm to continue'

                msg = msg.format(name)
                self.add_error('has_confirmed', msg)
                self.need_to_confirm = True
                if hasattr(self, 'request'):
                    messages.warning(self.request, msg)

        return cleaned_data
Example #15
0
class ContactForm(forms.Form):
    name = CharField()
    email = EmailField()
    phone = CharField()
    message = CharField(widget=forms.Textarea)
    gdpr = BooleanField(
        required=True,
        label=mark_safe(
            _("I hereby consent to the processing of my personal data. "
              "The information is only collected and processed for processing the contact request and "
              "is only stored for the period of communication, but for a maximum of 6 months. If a contract"
              " is concluded based on this request, legal retention periods apply. "
              "For more information, see our <a href='/cms/privacy-policy'>privacy policy</a>"
              )))
    captcha = ReCaptchaField(widget=ReCaptchaV2Checkbox)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        settings = ShopSetting.objects.first()

        self.fields['captcha'] = ReCaptchaField(
            widget=ReCaptchaV2Checkbox,
            public_key=settings.google_recaptcha_publickey,
            private_key=settings.google_recaptcha_privatekey)
Example #16
0
class MessageForm(ModelForm):
    to_all = BooleanField(required=False, label="Send to all subscribers?",
                          widget=CheckboxInput(
                              attrs={'class': 'to_all-checkbox'}))

    def __init__(self, *args, **kwargs):
        super(MessageForm, self).__init__(*args, **kwargs)
        instance = kwargs.get('instance', {})
        self.helper = FormHelper(self)
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-lg-2'
        self.helper.field_class = 'col-lg-8'
        self.helper.layout.append(Submit('message_send', 'Send Message'))
        self.helper.layout.append(HTML(
            '<a href="{}" class="btn btn-default" role="button">{}</a>'.format(
                reverse_lazy('messages', kwargs={}),
                'Cancel')
        ))

    def clean(self):
        cleaned_data = super(MessageForm, self).clean()
        to_all = cleaned_data.get("to_all", None)

        if to_all and "recipients" in self._errors:
            del self._errors["recipients"]

        return cleaned_data

    class Meta:
        model = Message
        fields = ['recipients', 'to_all', 'message']
        widgets = {
            'recipients': autocomplete.ModelSelect2Multiple(
                url='contact-autocomplete'),
            'message': Textarea(attrs={'rows': 4}),
        }
Example #17
0
class QueryForm(ModelForm):

    sql = SqlField()
    snapshot = BooleanField(widget=CheckboxInput, required=False)
    connection = CharField(widget=Select, required=False)

    def __init__(self, *args, **kwargs):
        super(QueryForm, self).__init__(*args, **kwargs)
        self.fields['connection'].widget.choices = self.connections
        if not self.instance.connection:
            self.initial[
                'connection'] = app_settings.EXPLORER_DEFAULT_CONNECTION
        self.fields['connection'].widget.attrs['class'] = 'form-control'

    def clean(self):
        if self.instance and self.data.get('created_by_user', None):
            self.cleaned_data[
                'created_by_user'] = self.instance.created_by_user
        return super(QueryForm, self).clean()

    @property
    def created_by_user_email(self):
        return self.instance.created_by_user.email if self.instance.created_by_user else '--'

    @property
    def created_at_time(self):
        return self.instance.created_at.strftime('%Y-%m-%d')

    @property
    def connections(self):
        return zip(app_settings.EXPLORER_CONNECTIONS.values(),
                   app_settings.EXPLORER_CONNECTIONS.keys())

    class Meta:
        model = Query
        fields = ['title', 'sql', 'description', 'snapshot', 'connection']
Example #18
0
class CoffeeMeetingForm(ModelForm):
    class Meta:
        model = CoffeeMeeting
        fields = ['title', 'content', 'cafe', 'meeting_date', 'max_participants']
        widgets = {'meeting_date': DateTimeInput(attrs={'id': 'inline_datetimepicker'})}

    images = forms.FileField(widget=ClearableFileInput(attrs={'multiple': True}), label='카페 사진',
                             help_text='카페 사진이 있으면 첨부해주세요!', required=False)
    save_cafephoto = BooleanField(required=False,initial=False, label='카페 정보에 사진을 등록할까요?',
                                  help_text='체크하면 카페 정보가 업데이트됩니다! 본인이 찍은 사진이면 등록해주세요!')

    def __init__(self, *args, **kwargs):
        # kwargs에서 form을 만드는데 필요없는 view에서 넘겨준 부가정보를 먼저 빼낸다
        self.request = kwargs.pop('request', None)
        self.cafe = kwargs.pop('cafes')
        read_only = kwargs.pop('read_only')

        # form을 생성하고 필요한 처리를 한다
        super(CoffeeMeetingForm, self).__init__(*args, **kwargs)
        self.fields['cafe'].initial = self.cafe

        # UpdateView에서 넘어온 경우 cafe를 활성화한다
        if read_only:
            self.fields['cafe'].widget.attrs['readonly'] = True
        self.fields['meeting_date'].input_formats = ["%Y-%m-%d %I:%M %p"]

    def clean_cafe(self):
        # 카페의 경우 항상 url 인자로 넘어온 카페를 리턴해야 한다
        return self.cafe

    def save(self, commit=True):
        instance = super(CoffeeMeetingForm, self).save(commit=False)
        instance.author = self.request.user
        instance.cafe = self.cafe
        instance.save()
        return instance
Example #19
0
class RegisterUserForm(UserCreationForm):
    delegate = BooleanField(label='add Delegate?', required=False)

    class Meta:
        model = User
        fields = (
            'first_name',
            'last_name',
            'email',
            'username',
            'password1',
            'password2',
        )
        widgets = {
            'email': TextInput(attrs={
                'type': 'email',
            }),
            'password1': TextInput(attrs={
                'type': 'password',
            }),
            'password2': TextInput(attrs={
                'type': 'password',
            }),
        }
Example #20
0
class SafetyIssueCreationForm(ModelForm):
    report_anonymously = BooleanField(required=False, initial=False)

    class Meta:
        model = SafetyIssue
        fields = ["reporter", "concern", "location"]

    def __init__(self, user, *args, **kwargs):
        super(SafetyIssueCreationForm, self).__init__(*args, **kwargs)
        self.user = user

    def clean_update(self):
        return self.cleaned_data["concern"].strip()

    def clean_location(self):
        return self.cleaned_data["location"].strip()

    def save(self, commit=True):
        instance = super(SafetyIssueCreationForm, self).save(commit=False)
        if not self.cleaned_data["report_anonymously"]:
            self.instance.reporter = self.user
        if commit:
            instance.save()
        return super(SafetyIssueCreationForm, self).save(commit=commit)
Example #21
0
class CodeGlobalPermissionsForm(Form):
    onlyAuthUsers = BooleanField(
        label="Solo permitir acceso por usuarios autenticados?",
        required=False)
    onlyCollaborators = BooleanField(
        label="Solo permitir acceso por usuarios explicitamente permitidos?",
        required=False)
    globalCanWrite = BooleanField(
        label="Acceso global al grupo definido anteriormente de escritura?",
        required=False)
    globalCanRead = BooleanField(
        label="Acceso global al grupo definido anteriormente de lectura?",
        required=False)
    globalCanExecute = BooleanField(
        label="Acceso global al grupo definido anteriormente de ejecucion?",
        required=False)
    globalCanDownload = BooleanField(
        label="Acceso global al grupo definido anteriormente de descargar?",
        required=False)
class WorkerForm(DocumentForm):
    """ Worker form representation
    """
    h2direct           = BooleanField(required=False, widget=CheckboxInput(attrs={"class": "js-switch"}))
    h2moderntlsonly    = BooleanField(required=False, widget=CheckboxInput(attrs={"class": "js-switch"}))
    h2push             = BooleanField(required=False, widget=CheckboxInput(attrs={"class": "js-switch"}))
    h2direct           = BooleanField(required=False, widget=CheckboxInput(attrs={"class": "js-switch"}))
    h2serializeheaders = BooleanField(required=False, widget=CheckboxInput(attrs={"class": "js-switch"}))
    h2upgrade          = BooleanField(required=False, widget=CheckboxInput(attrs={"class": "js-switch"}))

    def __init__(self, *args, **kwargs):
        super(WorkerForm, self).__init__(*args, **kwargs)

        self = bootstrap_tooltips(self)

    class Meta:
        document = Worker
        widgets = {
            'name': TextInput(attrs={'class': 'form-control'}),
            'gracefulshutdowntimeout': TextInput(attrs={'class': 'form-control'}),
            'maxconnectionsperchild': TextInput(attrs={'class': 'form-control'}),
            'minsparethreads': TextInput(attrs={'class': 'form-control'}),
            'maxsparethreads': TextInput(attrs={'class': 'form-control'}),
            'serverlimit': TextInput(attrs={'class': 'form-control'}),
            'threadsperchild': TextInput(attrs={'class': 'form-control'}),
            'rate_limit': TextInput(attrs={'class': 'form-control'}),
            'req_timeout_header': TextInput(attrs={'class': 'form-control'}),
            'req_timeout_body': TextInput(attrs={'class': 'form-control'}),
            'req_timeout_header_rate': TextInput(attrs={'class': 'form-control'}),
            'req_timeout_body_rate': TextInput(attrs={'class': 'form-control'}),
            'timeout': TextInput(attrs={'class': 'form-control'}),
            'maxkeepaliverequests': TextInput(attrs={'class': 'form-control'}),
            'keepalivetimeout': TextInput(attrs={'class': 'form-control'}),
            'h2maxsessionstreams': TextInput(attrs={'class': 'form-control'}),
            'h2maxworkeridleseconds': TextInput(attrs={'class': 'form-control'}),
            'h2minworkers': TextInput(attrs={'class': 'form-control'}),
            'h2maxworkers': TextInput(attrs={'class': 'form-control'}),
            'h2streammaxmemsize': TextInput(attrs={'class': 'form-control'}),
            'h2tlscooldownsecs': TextInput(attrs={'class': 'form-control'}),
            'h2tlswarmupsize': TextInput(attrs={'class': 'form-control'}),
            'h2windowsize': TextInput(attrs={'class': 'form-control'}),
        }
Example #23
0
class ReaderStudyCopyForm(Form):
    title = CharField(required=True)
    copy_images = BooleanField(required=False, initial=True)
    copy_hanging_list = BooleanField(required=False, initial=True)
    copy_case_text = BooleanField(required=False, initial=True)
    copy_questions = BooleanField(required=False, initial=True)
    copy_readers = BooleanField(required=False, initial=True)
    copy_editors = BooleanField(required=False, initial=True)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.layout.append(Submit("save", "Copy"))

    def clean(self, *args, **kwargs):
        if (
            self.cleaned_data["copy_hanging_list"]
            or self.cleaned_data["copy_case_text"]
        ) and not self.cleaned_data["copy_images"]:
            self.add_error(
                error="Hanging list and case text can only be copied if the images are copied as well",
                field=None,
            )
Example #24
0
class ChmodForm(forms.Form):
    op = "chmod"
    path = PathField(label=_("Path to change permissions"))

    # By default, BooleanField only validates when
    # it's checked.
    user_read = BooleanField(required=False)
    user_write = BooleanField(required=False)
    user_execute = BooleanField(required=False)
    group_read = BooleanField(required=False)
    group_write = BooleanField(required=False)
    group_execute = BooleanField(required=False)
    other_read = BooleanField(required=False)
    other_write = BooleanField(required=False)
    other_execute = BooleanField(required=False)
    sticky = BooleanField(required=False)
    recursive = BooleanField(required=False)

    names = ("user_read", "user_write", "user_execute", "group_read",
             "group_write", "group_execute", "other_read", "other_write",
             "other_execute", "sticky")

    def __init__(self, initial, *args, **kwargs):
        logging.info(dir(self))
        logging.info(dir(type(self)))
        # Convert from string representation.
        mode = initial.get("mode")
        if mode is not None:
            mode = int(mode, 8)
            bools = rwx.expand_mode(mode)
            for name, b in zip(self.names, bools):
                initial[name] = b
        logging.debug(initial)
        kwargs['initial'] = initial
        forms.Form.__init__(self, *args, **kwargs)

    def full_clean(self):
        forms.Form.full_clean(self)
        if hasattr(self, "cleaned_data"):
            self.cleaned_data["mode"] = rwx.compress_mode(
                map(lambda name: self.cleaned_data[name], self.names))
 def test_booleanfield_changed(self):
     f = BooleanField()
     self.assertFalse(f.has_changed(None, None))
     self.assertFalse(f.has_changed(None, ''))
     self.assertFalse(f.has_changed('', None))
     self.assertFalse(f.has_changed('', ''))
     self.assertTrue(f.has_changed(False, 'on'))
     self.assertFalse(f.has_changed(True, 'on'))
     self.assertTrue(f.has_changed(True, ''))
     # Initial value may have mutated to a string due to show_hidden_initial (#19537)
     self.assertTrue(f.has_changed('False', 'on'))
     # HiddenInput widget sends string values for boolean but doesn't clean them in value_from_datadict
     self.assertFalse(f.has_changed(False, 'False'))
     self.assertFalse(f.has_changed(True, 'True'))
     self.assertTrue(f.has_changed(False, 'True'))
     self.assertTrue(f.has_changed(True, 'False'))
 def test_boolean_picklable(self):
     self.assertIsInstance(pickle.loads(pickle.dumps(BooleanField())), BooleanField)
 def test_booleanfield_clean_2(self):
     f = BooleanField(required=False)
     self.assertEqual(False, f.clean(''))
     self.assertEqual(False, f.clean(None))
     self.assertEqual(True, f.clean(True))
     self.assertEqual(False, f.clean(False))
     self.assertEqual(True, f.clean(1))
     self.assertEqual(False, f.clean(0))
     self.assertEqual(True, f.clean('1'))
     self.assertEqual(False, f.clean('0'))
     self.assertEqual(True, f.clean('Django rocks'))
     self.assertEqual(False, f.clean('False'))
     self.assertEqual(False, f.clean('false'))
     self.assertEqual(False, f.clean('FaLsE'))
 def test_booleanfield_clean_1(self):
     f = BooleanField()
     with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
         f.clean('')
     with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
         f.clean(None)
     self.assertTrue(f.clean(True))
     with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
         f.clean(False)
     self.assertTrue(f.clean(1))
     with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
         f.clean(0)
     self.assertTrue(f.clean('Django rocks'))
     self.assertTrue(f.clean('True'))
     with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
         f.clean('False')
Example #29
0
class TripForm(TripFormBase):
    day_11 = BooleanField(label='day_11', required=False)
    day_12 = BooleanField(label='day_12', required=False)
    day_13 = BooleanField(label='day_13', required=False)
    day_14 = BooleanField(label='day_14', required=False)
    day_15 = BooleanField(label='day_15', required=False)
    day_16 = BooleanField(label='day_16', required=False)
    day_17 = BooleanField(label='day_17', required=False)
    day_21 = BooleanField(label='day_21', required=False)
    day_22 = BooleanField(label='day_22', required=False)
    day_23 = BooleanField(label='day_23', required=False)
    day_24 = BooleanField(label='day_24', required=False)
    day_25 = BooleanField(label='day_25', required=False)
    day_26 = BooleanField(label='day_26', required=False)
    day_27 = BooleanField(label='day_27', required=False)

    class Meta(TripFormBase.Meta):
        fields = TripFormBase.Meta.fields + [
            'text',
            'day_11',
            'day_12',
            'day_13',
            'day_14',
            'day_15',
            'day_16',
            'day_17',
            'day_21',
            'day_22',
            'day_23',
            'day_24',
            'day_25',
            'day_26',
            'day_27',
        ]
        widgets = {
            'week':
            NumberInput(attrs={"class": "week-style"}),
            'year':
            NumberInput(attrs={"class": "year-style"}),
            'price':
            NumberInput(attrs={
                "step": "0.01",
                "class": "price-style"
            }),
            'text':
            Textarea(attrs={
                'rows': 3,
                'cols': 10,
                'placeholder': _('add note').capitalize()
            })
        }

    def __init__(self, user, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['driver'].queryset = Person.objects.filter(
            user=user).order_by('name')
        self.fields['passenger'].queryset = Person.objects.filter(
            user=user).order_by('name')

    def clean_year(self):
        data = self.cleaned_data['year']
        if (data < 2000) or (data > 2100):
            self.add_error('year', 'Ожидался год в диапазоне от 2000 до 2100')
        return data

    def clean_week(self):
        data = self.cleaned_data['week']
        if (data < 1) or (data > 53):
            self.add_error('week',
                           'Ожидался номер недели в диапазоне от 1 до 53')
        return data

    def clean_price(self):
        data = self.cleaned_data['price']
        if (data == 0):
            self.add_error('price', 'Цена должна быть указана')
        return data

    def clean(self):
        super().clean()
        if (self.cleaned_data['driver'] == self.cleaned_data['passenger']):
            self.add_error('passenger', 'Укажите другого пассажира')
            raise ValidationError('Водитель и Пассажир должны отличаться')

        self.cleaned_data['days'] = 0
        for i in range(2):
            for j in range(7):
                if self.cleaned_data['day_' + str(i + 1) + str(j + 1)]:
                    self.cleaned_data['days'] = self.cleaned_data['days'] + (
                        1 << (i + j * 2))
        if (self.cleaned_data['oper'] == 0) and (self.cleaned_data['days']
                                                 == 0):
            raise ValidationError('Не отмечены дни недели')
Example #30
0
class SummaryActionForm(QueryActionForm):
    size = IntegerField(initial=40)
    offset = IntegerField(initial=0)
    aggregations = BooleanField(initial=True, required=False)
Example #31
0
class BookingForm(ModelForm):
    """
    Control booking creation here.
    """
    optimised = BooleanField(
        required=False)  # Ask if we want to optimise, e.g. combine tables.

    class Meta:
        model = Booking
        fields = ['restaurant', 'party_size', 'date', 'time', 'length']

        widgets = {
            'restaurant':
            TextInput(),
            'date':
            SelectDateWidget(years=(datetime.date.today().year,
                                    datetime.date.today().year + 1))
        }

    def __init__(self, restaurant, *args, **kwargs):
        """
        Assign the restaurant and it's initial value - annoyingly this is it's pk for now. Make this readonly.

        Set time limits for booking:
        - Only allow bookings within the opening hours of a restaurant.
        - Don't allow more than 2 hours (Assuming this is a limit).

        :param restaurant: Restaurant obj, the restaurant we are booking for.
        """
        super(BookingForm, self).__init__(*args, **kwargs)
        self.restaurant = restaurant
        self.fields['restaurant'].initial = restaurant
        self.fields['restaurant'].widget.attrs['readonly'] = True

        self.fields['time'].widget = Select(choices=available_times(
            restaurant.opening_time, restaurant.closing_time))
        self.fields['length'].widget = Select(choices=available_times(
            datetime.time(0, 0, 0), datetime.time(3, 15, 0)))

    def clean(self):
        """
        Do some sense checking.

        Make sure the bookings are within the time limits of the restaurant. Ensure a time has been given.

        Figure out extra parameters for the Booking and remove excess stuff (e.g. optimise).
        """
        cleaned_data = super(BookingForm, self).clean()

        time = cleaned_data.get('time')
        length = cleaned_data.get('length')

        if time and length:
            if (datetime.datetime.combine(datetime.date.today(), time) +
                    length).time() > self.restaurant.closing_time:
                raise ValidationError(
                    'Booking exceeds restaurant closing time.')
        else:
            raise ValidationError('No time or length given.')

        # Great, timing is valid - lets get the end time to store.

        end_time = (datetime.datetime.combine(datetime.date.today(), time) +
                    length).time()
        cleaned_data['end_time'] = end_time

        # Now we need to find any spare tables.

        date = cleaned_data.get('date')
        party = cleaned_data.get('party_size')

        cleaned_data['table'] = self.restaurant.find_table(
            date,
            time,
            end_time,
            party,
            optimise=cleaned_data.pop('optimised'))

        if not cleaned_data[
                'table']:  # If there aren't any tables lets alert the customer
            raise ValidationError('No tables available for this time.')
Example #32
0
class ScriptForm(ModelForm):

    script_type = CharField(
        label="Script type",
        required=False,
        help_text="Script type",
        initial=str(SCRIPT_TYPE.TESTING),
    )

    hardware_type = CharField(
        label="Hardware type",
        required=False,
        help_text="The hardware type the script configures or tests.",
        initial=str(HARDWARE_TYPE.NODE),
    )

    parallel = CharField(
        label="Parallel",
        required=False,
        help_text="Whether the script may run in parallel with other scripts.",
        initial=str(SCRIPT_PARALLEL.DISABLED),
    )

    packages = CharField(
        label="Packages",
        required=False,
        help_text="Packages to be installed with script.",
        initial="",
    )

    timeout = DurationField(
        label="Timeout",
        required=False,
        help_text="Timeout",
        initial=timedelta(0),
    )

    script = VersionedTextFileField(label="Script", help_text="Script content")

    comment = CharField(
        label="Comment",
        required=False,
        help_text="Description of change",
        initial="",
    )

    for_hardware = CharField(
        label="For hardware",
        required=False,
        help_text="Hardware identifiers this script requires to run.",
        initial="",
    )

    apply_configured_networking = BooleanField(required=False)

    class Meta:
        model = Script
        fields = (
            "name",
            "title",
            "description",
            "tags",
            "script_type",
            "hardware_type",
            "parallel",
            "packages",
            "timeout",
            "destructive",
            "script",
            "for_hardware",
            "may_reboot",
            "recommission",
            "apply_configured_networking",
        )

    def __init__(self, instance=None, data=None, edit_default=False, **kwargs):
        self.edit_default = edit_default
        if instance is None:
            script_data_key = "data"
        else:
            script_data_key = "new_data"

        data = data.copy()
        if "comment" in data and "script" in data:
            script_data = {
                "comment": data.get("comment"),
                script_data_key: data.get("script"),
            }
            data["script"] = script_data
            data.pop("comment")
        # Alias type to script_type to allow for consistent naming in the API.
        if "type" in data and "script_type" not in data:
            data["script_type"] = data["type"]
            # self.data is a QueryDict. pop returns a list containing the value
            # while directly accessing it returns just the value.
            data.pop("type")

        super().__init__(instance=instance, data=data, **kwargs)

        if instance is None:
            for field in ["name", "script"]:
                self.fields[field].required = True
        else:
            for field in ["name", "script"]:
                self.fields[field].required = False
            self.fields["script"].initial = instance.script

        # Reading the embedded YAML must happen at the end of initialization
        # so the fields set are validated.
        if "script" in self.data:
            self._read_script()

    def _validate_results(self, results={}):
        valid = True
        if isinstance(results, list):
            for result in results:
                if not isinstance(result, str):
                    set_form_error(
                        self,
                        "results",
                        "Each result in a result list must be a string.",
                    )
                    valid = False
        elif isinstance(results, dict):
            for result in results.values():
                if not isinstance(result, dict):
                    set_form_error(
                        self,
                        "results",
                        "Each result in a result dictionary must be a "
                        "dictionary.",
                    )
                elif "title" not in result:
                    set_form_error(
                        self,
                        "results",
                        "title must be included in a result dictionary.",
                    )
                    valid = False
                else:
                    for key in ["title", "description"]:
                        if key in result and not isinstance(result[key], str):
                            set_form_error(self, "results",
                                           "%s must be a string." % key)
                            valid = False
        else:
            set_form_error(
                self,
                "results",
                "results must be a list of strings or a dictionary of "
                "dictionaries.",
            )
            valid = False
        return valid

    def _clean_script(self, parsed_yaml):
        """Clean script data and validate input."""
        # Tags and timeout may not be updated from new embedded YAML. This
        # allows users to receive updated scripts from an upstream maintainer,
        # such as Canonical, while maintaining user defined tags and timeout.

        # Tags must be a comma seperated string for the form.
        tags = parsed_yaml.pop("tags", None)
        if (tags is not None and self.instance.id is None
                and "tags" not in self.data):
            tags_valid = True
            if isinstance(tags, str):
                self.data["tags"] = tags
            elif isinstance(tags, list):
                for tag in tags:
                    if not isinstance(tag, str):
                        tags_valid = False
                        continue
                if tags_valid:
                    self.data["tags"] = ",".join(tags)
            else:
                tags_valid = False
            if not tags_valid:
                set_form_error(
                    self,
                    "tags",
                    "Embedded tags must be a string of comma seperated "
                    "values, or a list of strings.",
                )

        # Timeout must be a string for the form.
        timeout = parsed_yaml.pop("timeout", None)
        if (timeout is not None and self.instance.id is None
                and "timeout" not in self.data):
            self.data["timeout"] = str(timeout)

        # Packages and for_hardware must be a JSON string for the form.
        for key in ["packages", "for_hardware"]:
            value = parsed_yaml.pop(key, None)
            if value is not None and key not in self.data:
                self.data[key] = json.dumps(value)

        for key, value in parsed_yaml.items():
            if key in self.fields:
                error = False
                if key not in self.data:
                    self.data[key] = value
                elif key == "script_type":
                    # The deprecated Commissioning API always sets the
                    # script_type to commissioning as it has always only
                    # accepted commissioning scripts while the form sets
                    # the default type to testing. If the YAML matches the
                    # type allow it.
                    try:
                        if translate_script_type(
                                value) != translate_script_type(
                                    self.data[key]):
                            error = True
                    except ValidationError:
                        error = True
                elif value != self.data[key]:
                    # Only allow form data for fields defined in the YAML if
                    # the data matches.
                    error = True

                if error:
                    set_form_error(
                        self,
                        key,
                        "May not override values defined in embedded YAML.",
                    )

    def _read_script(self):
        """Read embedded YAML configuration in a script.

        Search for supported MAAS script metadata in the script and
        read the values. Leading '#' are ignored. If the values are
        fields they will be entered in the form.
        """
        yaml_delim = re.compile(
            r"\s*#\s*-+\s*(Start|End) MAAS (?P<version>\d+\.\d+) "
            r"script metadata\s+-+",
            re.I,
        )
        found_version = None
        yaml_content = ""

        if isinstance(self.data["script"], dict):
            if "new_data" in self.data["script"]:
                script = self.data["script"]["new_data"]
            else:
                script = self.data["script"]["data"]
        else:
            script = self.data["script"]

        script_splitlines = script.splitlines()
        if len(script_splitlines) >= 1 and not script_splitlines[0].startswith(
                "#!/"):
            set_form_error(self, "script", "Must start with shebang.")

        for line in script_splitlines[1:]:
            m = yaml_delim.search(line)
            if m is not None:
                if found_version is None and m.group("version") == "1.0":
                    # Found the start of the embedded YAML
                    found_version = m.group("version")
                    continue
                elif found_version == m.group("version"):
                    # Found the end of the embedded YAML
                    break
            elif found_version is not None and line.strip() != "":
                # Capture all lines inbetween the deliminator
                if "#" not in line:
                    set_form_error(self, "script", 'Missing "#" on YAML line.')
                    return
                yaml_content += "%s\n" % line.split("#", 1)[1]

        try:
            parsed_yaml = yaml.safe_load(yaml_content)
        except yaml.YAMLError as err:
            set_form_error(self, "script", "Invalid YAML: %s" % err)
            return

        if not isinstance(parsed_yaml, dict):
            return

        self.instance.results = parsed_yaml.pop("results", {})
        self.instance.parameters = parsed_yaml.pop("parameters", {})

        self._clean_script(parsed_yaml)

    def clean_packages(self):
        if self.cleaned_data["packages"] == "":
            return self.instance.packages
        else:
            packages = json.loads(self.cleaned_data["packages"])

            # Automatically convert into a list incase only one package is
            # needed.
            for key in ["apt", "snap", "url"]:
                if key in packages and not isinstance(packages[key], list):
                    packages[key] = [packages[key]]

            for key in ["apt", "url"]:
                if key in packages:
                    for package in packages[key]:
                        if not isinstance(package, str):
                            set_form_error(
                                self,
                                "packages",
                                "Each %s package must be a string." % key,
                            )
            if "snap" in packages:
                for package in packages["snap"]:
                    if isinstance(package, dict):
                        if "name" not in package or not isinstance(
                                package["name"], str):
                            set_form_error(
                                self,
                                "packages",
                                "Snap package name must be defined.",
                            )
                        if "channel" in package and package["channel"] not in [
                                "stable",
                                "edge",
                                "beta",
                                "candidate",
                        ]:
                            set_form_error(
                                self,
                                "packages",
                                "Snap channel must be stable, edge, beta, "
                                "or candidate.",
                            )
                        if "mode" in package and package["mode"] not in [
                                "classic",
                                "dev",
                                "jail",
                        ]:
                            set_form_error(
                                self,
                                "packages",
                                "Snap mode must be classic, dev, or jail.",
                            )
                    elif not isinstance(package, str):
                        set_form_error(self, "packages",
                                       "Snap package must be a string.")
            return packages

    def clean_for_hardware(self):
        """Convert from JSON and validate for_hardware input."""
        if self.cleaned_data["for_hardware"] == "":
            return self.instance.for_hardware
        try:
            for_hardware = json.loads(self.cleaned_data["for_hardware"])
        except JSONDecodeError:
            for_hardware = self.cleaned_data["for_hardware"]
        if isinstance(for_hardware, str):
            for_hardware = for_hardware.split(",")
        if not isinstance(for_hardware, list):
            set_form_error(self, "for_hardware", "Must be a list or string")
            return
        regex = re.compile(
            r"^modalias:.+|pci:[\da-f]{4}:[\da-f]{4}|"
            r"usb:[\da-f]{4}:[\da-f]{4}|"
            r"system_vendor:.*|"
            r"system_product:.*|"
            r"system_version:.*|"
            r"mainboard_vendor:.*|"
            r"mainboard_product:.*$",
            re.I,
        )
        for hw_id in for_hardware:
            if regex.search(hw_id) is None:
                set_form_error(
                    self,
                    "for_hardware",
                    "Hardware identifier '%s' must be a modalias, PCI ID, "
                    "USB ID, system vendor, system product, system version, "
                    "mainboard vendor, or mainboard product." % hw_id,
                )
        return for_hardware

    def clean(self):
        cleaned_data = super().clean()
        # If a field wasn't passed in keep the old values when updating.
        if self.instance.id is not None:
            for field in self._meta.fields:
                if field not in self.data:
                    cleaned_data[field] = getattr(self.instance, field)

        script_type = cleaned_data["script_type"]
        if script_type == "":
            cleaned_data["script_type"] = self.instance.script_type
        else:
            try:
                cleaned_data["script_type"] = translate_script_type(
                    script_type)
            except ValidationError as e:
                set_form_error(self, "script_type", e)

        hardware_type = cleaned_data["hardware_type"]
        if hardware_type == "":
            cleaned_data["hardware_type"] = self.instance.hardware_type
        else:
            try:
                cleaned_data["hardware_type"] = translate_hardware_type(
                    hardware_type)
            except ValidationError as e:
                set_form_error(self, "hardware_type", e)

        parallel = cleaned_data["parallel"]
        if parallel == "":
            cleaned_data["parallel"] = self.instance.parallel
        else:
            try:
                cleaned_data["parallel"] = translate_script_parallel(parallel)
            except ValidationError as e:
                set_form_error(self, "parallel", e)

        return cleaned_data

    def is_valid(self):
        valid = super().is_valid()

        if valid and self.instance.default and not self.edit_default:
            for field in self.Meta.fields:
                if field in ["tags", "timeout"]:
                    continue
                if field in self.data:
                    set_form_error(
                        self,
                        field,
                        "Not allowed to change on default scripts.",
                    )
                    valid = False

        name = self.data.get("name")
        # none is used to tell the API to not run testing_scripts during
        # commissioning.
        if name is not None and name.lower() == "none":
            set_form_error(self, "name", '"none" is a reserved name.')
            valid = False

        # The name can't be a digit as MAAS allows scripts to be selected by
        # id.
        if name is not None and name.isdigit():
            set_form_error(self, "name", "Cannot be a number.")
            valid = False

        if name is not None and pipes.quote(name) != name:
            set_form_error(
                self,
                "name",
                "Name contains disallowed characters, e.g. space or quotes.",
            )
            valid = False

        # If comment and script exist __init__ combines both fields into a dict
        # to pass to VersionedTextFileField.
        if "comment" in self.data:
            set_form_error(
                self,
                "comment",
                '"comment" may only be used when specifying a "script" '
                "as well.",
            )
            valid = False

        if "script" in self.data:
            if not self._validate_results(self.instance.results):
                valid = False

        if "parameters" in self.data:
            params_form = ParametersForm(data=self.data.get("parameters"))
            if not params_form.is_valid():
                valid = False

        if (not valid and self.instance.script_id is not None
                and self.initial.get("script") != self.instance.script_id
                and self.instance.script.id is not None):
            # If form validation failed cleanup any new VersionedTextFile
            # created by the VersionedTextFileField.
            self.instance.script.delete()
        return valid

    def save(self, *args, **kwargs):
        request = kwargs.pop("request", None)
        endpoint = kwargs.pop("endpoint", None)
        script = super(ScriptForm, self).save(*args, **kwargs)

        # Create audit event log if endpoint and request supplied.
        if request is not None and endpoint is not None:
            create_audit_event(
                EVENT_TYPES.SETTINGS,
                endpoint,
                request,
                None,
                description="Saved script '%s'." % script.name,
            )
        return script
Example #33
0
 def test_disabled_has_changed(self):
     f = BooleanField(disabled=True)
     self.assertIs(f.has_changed('True', 'False'), False)
Example #34
0
class CuratorSearchForm(Form):
    fullSearch = CharField(max_length=255, required=False)
    useMUIS = BooleanField(initial=False, required=False)
    useDIGAR = BooleanField(initial=False, required=False)
    useMKA = BooleanField(initial=False, required=False)
    useETERA = BooleanField(initial=False, required=False)
    useFlickr = BooleanField(initial=False, required=False)
    useUTLIB = BooleanField(initial=False, required=False)
    useFinna = BooleanField(initial=False, required=False)
    useCommons = BooleanField(initial=False, required=False)
    useEuropeana = BooleanField(initial=False, required=False)
    useFotis = BooleanField(initial=False, required=False)
    # Also used for Finna and Fotis
    flickrPage = IntegerField(initial=1, required=False)
    filterExisting = BooleanField(initial=True, required=False)
    ids = NotValidatedMultipleChoiceField(coerce=str, required=False)
Example #35
0
class CompleteProductBooleanForm(Form):
	checkbox = BooleanField(label = '', required = False)
Example #36
0
 def __init__(self, *args, **kwargs):
     BooleanField.__init__(self, required=False, *args, **kwargs)