class AnotherForm(Form): field3 = CharField(max_length=20, widget=MyWidget3())
class LoginForm(Form): username = CharField(label="User Name", max_length=64) password = CharField(widget=PasswordInput())
def test_null_characters_prohibited(self): f = CharField() msg = 'Null characters are not allowed.' with self.assertRaisesMessage(ValidationError, msg): f.clean('\x00something')
class EmailForm(Form): email_address = CharField(widget=EmailInput( attrs={'class': 'form-control'}))
def __init__(self, required=True, help_text=None, **kwargs): self.field = CharField(required=required, help_text=help_text, widget=MathJaxWidget()) super(MathBlock, self).__init__(**kwargs)
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( '\s*#\s*-+\s*(Start|End) MAAS (?P<version>\d+\.\d+) ' '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( '^modalias:.+|pci:[\da-f]{4}:[\da-f]{4}|' 'usb:[\da-f]{4}:[\da-f]{4}|' 'system_vendor:.*|' 'system_product:.*|' 'system_version:.*|' 'mainboard_vendor:.*|' '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
class TestForm(Form): test_field = CharField()
class UserInfoForm(forms.Form): personal_details: CharField = CharField(label="personal_details", max_length=500) money = CharField(label="money", max_length=200) letter_of_recommendation: CharField = forms.CharField(label="money", max_length=2000)
class CreateApplicationForm(forms.Form): students: CharField = CharField(label="students", max_length=200)
class LoginForm(AuthenticationForm): username = CharField(label="Kullanıcı Adı", widget=TextInput(attrs={'class': 'form-control', 'placeholder': 'Kullanıcı adı'})) password = CharField(label="Şifre", widget=PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Şifre'}))
class Form(klass): entry_description = CharField(label='备注', required=False) if not cls.use_today: entry_date = DateField(label='日期', initial=date.today())
class TextAreaAnswer(BaseAnswerForm): answer = CharField(widget=Textarea)
class TextInputAnswer(BaseAnswerForm): answer = CharField()
def add_hidden_field(self, name, initial): self.fields[name] = CharField(widget=HiddenInput, initial=initial, required=False)
class CoursePwForm(Form): password = CharField(label=_('Password'), max_length=255)
class LoginForm(Form): username = CharField() password = CharField(widget=PasswordInput()) remember_username = BooleanField(initial=True, widget=CheckboxInput())
class SubmissionForm(Form): problem_slug = CharField(widget=HiddenInput) flag = CharField(max_length=255)
class SongForm(ModelForm): cuex = CharField(widget=LinkWidget, required=False) scld = CharField(widget=LinkWidget, required=False) midi = CharField(widget=LinkWidget, required=False) playback_mp3 = CharField(widget=LinkWidget, required=False) recording_ogg = CharField(widget=LinkWidget, required=False) recording_mp3 = CharField(widget=LinkWidget, required=False) author_songs = CharField(widget=DirectLinkWidget, required=False) song_Embed_Description = CharField(widget=DirectLinkWidget, required=False) user_info = CharField(widget=DirectLinkWidget, required=False) song_counters = CharField(widget=DirectLinkWidget, required=False) def __init__(self, *args, **kwargs): super(SongForm, self).__init__(*args, **kwargs) self.set_initial_values() def set_initial_values(self): api_base_url = "https://my.scorecloud.com/api/2.0/song/" if self.instance.source_type == "recording": self.fields[ 'recording_ogg'].initial = api_base_url + self.instance.song_id + "/recording.ogg" self.fields[ 'recording_mp3'].initial = api_base_url + self.instance.song_id + "/recording.mp3" self.fields[ 'cuex'].initial = api_base_url + self.instance.song_id + "/cuex" self.fields[ 'scld'].initial = api_base_url + self.instance.song_id + "/song.scld" self.fields[ 'midi'].initial = api_base_url + self.instance.song_id + "/playback.midi" self.fields[ 'playback_mp3'].initial = api_base_url + self.instance.song_id + "/playback.mp3" self.fields['author_songs'].initial = get_song_author_link( self.instance.author) self.fields['song_Embed_Description'].initial = get_song_meta_link( self.instance) self.fields['user_info'].initial = get_user_info_link( self.instance.author) self.fields['song_counters'].initial = get_song_counters_link( self.instance) class Meta: model = Song fields = ( 'song_id', 'source_type', 'title', 'creation_date', 'is_active', 'is_shared', 'is_deleted', 'song_Embed_Description', 'is_unsorted', 'current_scld_id', 'meta', 'current_revision_id', 'last_update', 'permissions', 'is_public', 'popularity', 'maturity', )
class RequestForm(ModelForm): cstatus = CharField(label='Status', required=False) class Meta: model = TRequest
class ChoiceFieldExclusionForm(ModelForm): multi_choice = CharField(max_length=50) class Meta: exclude = ['multi_choice'] model = ChoiceFieldModel
class CreateUserForm(Form): appuseruuid = CharField(widget=HiddenInput()) email = CharField(widget=EmailInput(attrs={'class': 'form-control'})) username = CharField(widget=TextInput(attrs={'class': 'form-control'})) first_name = CharField(widget=TextInput(attrs={'class': 'form-control'})) last_name = CharField(widget=TextInput(attrs={'class': 'form-control'})) password = CharField(widget=PasswordInput(attrs={'class': 'form-control'})) confirm_password = CharField(widget=PasswordInput( attrs={'class': 'form-control'})) user_agreement_consent = BooleanField(label=mark_safe( 'I have read and agree to the <a href="/end-user-license/">user license agreement</a>' ), widget=CheckboxInput()) privacy_policy_consent = BooleanField(label=mark_safe( 'I have read and agree to the <a href="/privacy-policy/">privacy policy</a>' ), widget=CheckboxInput()) def __init__(self, registration_type='website', *args, **kwargs): super(CreateUserForm, self).__init__(*args, **kwargs) # self.fields['username'].help_text = 'Minimum 3 characters. Letters, numbers, and underscores only.' self.fields[ 'password'].help_text = 'Minimum 8 characters. Must contain at least 1 letter, 1 number and 1 special character.' self.registration_type = registration_type if registration_type == 'invitation': self.fields['email'].widget = EmailInput( attrs={'class': 'form-control'}) else: self.fields['email'].widget = HiddenInput() self.fields['user_agreement_consent'].widget = HiddenInput( attrs={'value': 'checked'}) self.fields['privacy_policy_consent'].widget = HiddenInput( attrs={'value': 'checked'}) if settings.MAKE_USERNAME_EMAIL: self.fields['username'].widget = HiddenInput() self.fields['username'].required = False else: self.fields['username'].widget = TextInput( attrs={'class': 'form-control'}) def clean(self): """ Enforces username and password requirements """ super(CreateUserForm, self).clean() data = self.cleaned_data errors = [] clean_password = self.cleaned_data['password'] confirm_password = self.cleaned_data['confirm_password'] password_errors = validate_password(clean_password, confirm_password) if password_errors: errors.append(password_errors) clean_email = self.cleaned_data['email'] email_error = validate_email(clean_email, 0) if email_error: errors.append(email_error) if self.registration_type == 'invitation': email_is_unique = validate_unique_email(clean_email, 0) if not settings.MAKE_USERNAME_EMAIL: username_is_unique = validate_unique_username( self.cleaned_data['username'], 0) if errors: raise ValidationError(mark_safe('<br />'.join(errors))) return data
class ProjectForm(forms.Form): project_slug = CharField(label='App Name', max_length=100, widget=TextInput(attrs={ 'readonly': 'readonly', 'class': 'form-control' })) organisation_name = CharField( label='Name der Genossenschaft', max_length=100, widget=TextInput(attrs={'class': 'form-control'})) street = CharField(label='Strasse', max_length=100, widget=TextInput(attrs={'class': 'form-control'})) number = CharField(label='Nummer', max_length=100, widget=TextInput(attrs={'class': 'form-control'})) zip = CharField(label='PLZ', max_length=100, widget=TextInput(attrs={'class': 'form-control'})) city = CharField(label='Stadt', max_length=100, widget=TextInput(attrs={'class': 'form-control'})) extra = CharField(label='AdressZusatz', max_length=100, widget=TextInput(attrs={'class': 'form-control'}), required=False) PC = CharField(label='PC Kontonummer', max_length=100, widget=TextInput(attrs={'class': 'form-control'})) IBAN = CharField(label='IBAN', max_length=100, widget=TextInput(attrs={'class': 'form-control'})) BIC = CharField(label='BIC', max_length=100, widget=TextInput(attrs={'class': 'form-control'})) NAME = CharField(label='Name der Bank', max_length=100, widget=TextInput(attrs={'class': 'form-control'})) ESR = CharField(label='ESR falls vorhanden', max_length=100, widget=TextInput(attrs={'class': 'form-control'}), required=False) info_email = CharField(label='info email adresse', max_length=100, widget=TextInput(attrs={'class': 'form-control'})) share_price = CharField(label='Preis eines Anteilscheines', max_length=100, widget=TextInput(attrs={'class': 'form-control'}))
class UserProfileEmailUsernameForm(UserProfileForm): user_id = CharField(widget=HiddenInput()) email = EmailField(widget=EmailInput(attrs={'class': 'form-control'})) first_name = CharField(widget=TextInput(attrs={'class': 'form-control'})) last_name = CharField(widget=TextInput(attrs={'class': 'form-control'}))
class DomainForm(forms.Form): domain = CharField(label='Domain', max_length=100, widget=TextInput(attrs={'class': 'form-control'}))
class NameForm(Form): your_name = CharField(label='Your name', max_length=100)
def test_disabled_has_changed(self): f = MultiValueField(fields=(CharField(), CharField()), disabled=True) self.assertIs(f.has_changed(['x', 'x'], ['y', 'y']), False)
def test_charfield_disabled(self): f = CharField(disabled=True) self.assertWidgetRendersTo( f, '<input type="text" name="f" id="id_f" disabled required>')
class ForgotUsernameForm(Form): email = CharField(label="Email address", max_length=256)
class ExcludingForm(ModelForm): name = CharField(max_length=255) class Meta: model = Defaults exclude = ['name', 'callable_default']
class MyForm(Form): field1 = CharField(max_length=20, widget=MyWidget1()) field2 = CharField(max_length=20, widget=MyWidget2())