def test_filefield_changed(self): """ The value of data will more than likely come from request.FILES. The value of initial data will likely be a filename stored in the database. Since its value is of no use to a FileField it is ignored. """ f = FileField() # No file was uploaded and no initial data. self.assertFalse(f.has_changed('', None)) # A file was uploaded and no initial data. self.assertTrue(f.has_changed('', {'filename': 'resume.txt', 'content': 'My resume'})) # A file was not uploaded, but there is initial data self.assertFalse(f.has_changed('resume.txt', None)) # A file was uploaded and there is initial data (file identity is not dealt # with here) self.assertTrue(f.has_changed('resume.txt', {'filename': 'resume.txt', 'content': 'My resume'}))
def test_filefield_2(self): f = FileField(max_length=5) with self.assertRaisesMessage(ValidationError, "'Ensure this filename has at most 5 characters (it has 18).'"): f.clean(SimpleUploadedFile('test_maxlength.txt', b'hello world')) self.assertEqual('files/test1.pdf', f.clean('', 'files/test1.pdf')) self.assertEqual('files/test2.pdf', f.clean(None, 'files/test2.pdf')) self.assertIsInstance(f.clean(SimpleUploadedFile('name', b'Some File Content')), SimpleUploadedFile)
class UserRegistroForm(UserCreationForm): clave_rh = ChoiceField( label="Id Empleado", widget=Select( attrs={'class': 'form-control input-xs'} ) ) clave_jde = CharField( label="Clave de JDE", widget=HiddenInput() ) foto = FileField( label="Foto", widget=ClearableFileInput( attrs={'class': 'dropzone dz-clickable dz-started'} ), ) password1 = CharField( label="Contraseña", widget=PasswordInput( attrs={'class': 'form-control input-xs'} ) ) password2 = CharField( label="Confirmar Contraseña", widget=PasswordInput( attrs={'class': 'form-control input-xs'} ) ) rfc = CharField( label="RFC", widget=TextInput( attrs={'class': 'form-control input-xs'} ) ) fecha_nacimiento = DateField( widget=HiddenInput() ) accept_terms = BooleanField( widget=CheckboxInput() ) class Meta: model = User fields = [ 'username', 'first_name', 'last_name', 'email', 'clave_rh', 'clave_jde', 'foto', 'password1', 'password2', 'rfc', 'accept_terms' ] labels = { 'username': '******', 'first_name': 'Nombre', 'last_name': 'Apellidos', 'email': 'Email', } widgets = { 'username': HiddenInput(attrs={'class': 'form-control input-xs'}), 'first_name': HiddenInput(attrs={'class': 'form-control input-xs', 'readonly': 'True'}), 'last_name': HiddenInput(attrs={'class': 'form-control input-xs', 'readonly': 'True'}), 'email': TextInput(attrs={'class': 'form-control input-xs', 'required': 'required'}), } def __init__(self, *args, **kwargs): super(UserRegistroForm, self).__init__(*args, **kwargs) self.fields['username'].required = False self.fields['first_name'].required = False self.fields['last_name'].required = False self.fields['email'].required = True self.fields['rfc'].required = True self.fields[ 'clave_rh'].choices = EmpleadoBusiness.get_SinUsuario_ForSelect() self.fields['clave_jde'].required = False self.fields['foto'].required = False self.fields['fecha_nacimiento'].required = False self.fields['accept_terms'].required = True def clean(self): cleaned_data = super(UserRegistroForm, self).clean() clave_rh = cleaned_data.get("clave_rh") rfc = cleaned_data.get("rfc") password1 = cleaned_data.get("password1") password2 = cleaned_data.get("password2") email = cleaned_data.get("email") accept_terms = cleaned_data.get("accept_terms") if clave_rh and rfc and email and password1 and password2 and accept_terms: try: datos = EmpleadoBusiness.get_ByNumero(clave_rh) except Exception as error: raise ValidationError( str(error) ) if datos.pers_empleado_numero: ebs_rfc = datos.pers_rfc.replace("-", "") rfc = rfc.replace("-", "").upper() if ebs_rfc != rfc: raise ValidationError( 'No existe un usuario con el RFC proporcionado') username = datos.pers_empleado_numero first_name = "%s %s" % ( datos.pers_primer_nombre, datos.pers_segundo_nombre.replace("-", "")) last_name = "%s %s" % ( datos.pers_apellido_paterno, datos.pers_apellido_materno.replace("-", "")) self.cleaned_data["username"] = username self.cleaned_data["first_name"] = first_name self.cleaned_data["last_name"] = last_name fecha = parser.parse(datos.pers_fecha_nacimiento) self.cleaned_data["fecha_nacimiento"] = fecha.date() return self.cleaned_data else: raise ValidationError( "El empleado no tiene un numero especificado" )
class ExistingDataForm(ModelForm): """Form for creating a new Existing Data Tracking instance.""" teams = ModelMultipleChoiceField( widget=SelectMultiple({'class': 'form-control mb-2', 'placeholder': 'Teams'}), queryset=Team.objects.none(), label=_("Share With Teams"), required=False) work = CharField( max_length=255, widget=TextInput({'class': 'form-control mb-2', 'placeholder': 'Work Office/Lab'}), label=_("User Work Office/Lab"), required=True) email = CharField( max_length=255, widget=TextInput({'class': 'form-control mb-2', 'placeholder': 'Email'}), label=_("Email Address"), required=True) phone = CharField( max_length=32, widget=TextInput({'class': 'form-control mb-2', 'placeholder': '(555) 555-5555 or 555-555-5555'}), label=_("Phone Number"), required=True) search = CharField( max_length=255, widget=TextInput({'class': 'form-control mb-2', 'placeholder': 'Search Term'}), label=_("Search for Existing Data"), required=True) source = ModelChoiceField( label=_("Source"), queryset=ExistingDataSource.objects.all(), widget=Select(attrs={'class': 'form-control mb-2'}), initial=0) source_title = CharField( max_length=255, widget=TextInput({'class': 'form-control mb-2', 'placeholder': 'Source Title'}), label=_("Source Title"), required=True) keywords = CharField( max_length=1024, widget=Textarea({'rows': 2, 'class': 'form-control mb-2', 'placeholder': 'Keywords, Comma Seperated'}), label=_("Keywords"), required=False) url = CharField( max_length=255, widget=TextInput({'class': 'form-control mb-2', 'placeholder': 'https://www.epa.gov/'}), label=_("Source URL Link"), required=True) disclaimer_req = BooleanField(label=_("EPA Discaimer Required"), required=False, initial=False, widget=RadioSelect(choices=YES_OR_NO)) citation = CharField( max_length=2048, widget=Textarea({'rows': 3, 'class': 'form-control mb-2', 'placeholder': 'Citation'}), label=_("Citation"), required=True) comments = CharField( max_length=2048, widget=Textarea({'rows': 3, 'class': 'form-control mb-2', 'placeholder': 'Comments'}), label=_("Comments"), required=False) attachments = FileField(label=_("Upload File Attachments"), required=False, widget=ClearableFileInput( attrs={'multiple': False, 'class': 'custom-file-input'})) def __init__(self, *args, **kwargs): """Override default init to add custom queryset for teams.""" try: current_user = kwargs.pop('user') super(ExistingDataForm, self).__init__(*args, **kwargs) team_ids = TeamMembership.objects.filter( member=current_user).values_list('team', flat=True) self.fields['teams'].queryset = Team.objects.filter(id__in=team_ids) self.fields['teams'].label_from_instance = lambda obj: "%s" % obj.name except BaseException: super(ExistingDataForm, self).__init__(*args, **kwargs) class Meta: """Meta data for Existing Data Tracking.""" model = ExistingData fields = ('work', 'email', 'phone', 'search', 'source', 'source_title', 'keywords', 'url', 'citation', 'comments')
class QueryBuilderForm(forms.Form): """ Form to build an SQL query using a web interface. Works hand in hand with ``querybuilder.js`` on the client side; q.v. """ database = CharField(label="Schema", required=False) schema = CharField(label="Schema", required=True) table = CharField(label="Table", required=True) column = CharField(label="Column", required=True) datatype = CharField(label="Data type", required=True) offer_where = BooleanField(label="Offer WHERE?", required=False) # BooleanField generally needs "required=False", or you can't have False! where_op = CharField(label="WHERE comparison", required=False) date_value = DateField(label="Date value (e.g. 1900-01-31)", required=False) int_value = IntegerField(label="Integer value", required=False) float_value = FloatField(label="Float value", required=False) string_value = CharField(label="String value", required=False) file = FileField(label="File (for IN)", required=False) def __init__(self, *args, **kwargs) -> None: self.file_values_list = [] # type: List[Any] super().__init__(*args, **kwargs) def get_datatype(self) -> Optional[str]: return self.data.get('datatype', None) def is_datatype_unknown(self) -> bool: return self.get_datatype() == QB_DATATYPE_UNKNOWN def offering_where(self) -> bool: if self.is_datatype_unknown(): return False return self.data.get('offer_where', False) def get_value_fieldname(self) -> str: datatype = self.get_datatype() if datatype == QB_DATATYPE_INTEGER: return "int_value" if datatype == QB_DATATYPE_FLOAT: return "float_value" if datatype == QB_DATATYPE_DATE: return "date_value" if datatype in QB_STRING_TYPES: return "string_value" if datatype == QB_DATATYPE_UNKNOWN: return "" raise ValueError("Invalid field type") def get_cleaned_where_value(self) -> Any: # Only call this if you've already cleaned/validated the form! return self.cleaned_data[self.get_value_fieldname()] def clean(self) -> None: # Check the WHERE information is sufficient. if 'submit_select' in self.data or 'submit_select_star' in self.data: # Form submitted via the "Add" method, so no checks required. # http://stackoverflow.com/questions/866272/how-can-i-build-multiple-submit-buttons-django-form # noqa return if not self.offering_where(): return cleaned_data = super().clean() if not cleaned_data['where_op']: self.add_error('where_op', forms.ValidationError("Must specify comparison")) # No need for a value for NULL-related comparisons. But otherwise: where_op = cleaned_data['where_op'] if where_op not in SQL_OPS_VALUE_UNNECESSARY + SQL_OPS_MULTIPLE_VALUES: # Can't take 0 or many parameters, so need the standard single # value: value_fieldname = self.get_value_fieldname() value = cleaned_data.get(value_fieldname) if not value: self.add_error( value_fieldname, forms.ValidationError("Must specify WHERE condition")) # --------------------------------------------------------------------- # Special processing for file upload operations # --------------------------------------------------------------------- if where_op not in SQL_OPS_MULTIPLE_VALUES: return fileobj = cleaned_data['file'] # ... is an instance of InMemoryUploadedFile if not fileobj: self.add_error('file', forms.ValidationError("Must specify file")) return datatype = self.get_datatype() if datatype in QB_STRING_TYPES: form_to_python_fn = str elif datatype == QB_DATATYPE_DATE: form_to_python_fn = html_form_date_to_python elif datatype == QB_DATATYPE_INTEGER: form_to_python_fn = int_validator elif datatype == QB_DATATYPE_FLOAT: form_to_python_fn = float_validator else: # Safe defaults form_to_python_fn = str # Or: http://www.dabeaz.com/generators/Generators.pdf self.file_values_list = [] # type: List[Any] for line in fileobj.read().decode("utf8").splitlines(): raw_item = line.strip() if not raw_item or raw_item.startswith('#'): continue try: value = form_to_python_fn(raw_item) except (TypeError, ValueError): self.add_error('file', forms.ValidationError( f"File contains bad value: {raw_item!r}")) return self.file_values_list.append(value) if not self.file_values_list: self.add_error('file', forms.ValidationError( "No values found in file"))
class FormWithFile(Form): username = CharField() file = FileField()
class UploadFileForm(forms.Form): op = "upload" # The "hdfs" prefix in "hdfs_file" triggers the HDFSfileUploadHandler hdfs_file = FileField(forms.Form, label=_("File to Upload")) dest = PathField(label=_("Destination Path"), help_text=_("Filename or directory to upload to.")) extract_archive = BooleanField(required=False)
class KerberosKeytabCreateForm(ModelForm): keytab_file = FileField(label=_("Kerberos Keytab"), required=False) class Meta: fields = '__all__' model = models.KerberosKeytab def clean_keytab_file(self): keytab_file = self.cleaned_data.get("keytab_file", None) if not keytab_file: raise forms.ValidationError(_("A keytab is required.")) encoded = None if hasattr(keytab_file, 'temporary_file_path'): filename = keytab_file.temporary_file_path() with open(filename, "rb") as f: keytab_contents = f.read() encoded = base64.b64encode(keytab_contents).decode() else: filename = tempfile.mktemp(dir='/tmp') with open(filename, 'wb+') as f: for c in keytab_file.chunks(): f.write(c) with open(filename, "rb") as f: keytab_contents = f.read() encoded = base64.b64encode(keytab_contents).decode() os.unlink(filename) return encoded def save_principals(self, keytab): if not keytab: return False keytab_file = self.cleaned_data.get("keytab_file") regex = re.compile( '^(\d+)\s+([\w-]+(\s+\(\d+\))?)\s+([^\s]+)\s+([\d+\-]+)(\s+)?$') tmpfile = tempfile.mktemp(dir="/tmp") with open(tmpfile, 'wb') as f: decoded = base64.b64decode(keytab_file) f.write(decoded) (res, out, err) = run("/usr/sbin/ktutil -vk '%s' list" % tmpfile) if res != 0: log.debug("save_principals(): %s", err) os.unlink(tmpfile) return False os.unlink(tmpfile) ret = False out = out.splitlines() if not out: return False for line in out: line = line.strip() if not line: continue m = regex.match(line) if m: try: kp = models.KerberosPrincipal() kp.principal_keytab = keytab kp.principal_version = int(m.group(1)) kp.principal_encryption = m.group(2) kp.principal_name = m.group(4) kp.principal_timestamp = m.group(5) kp.save() ret = True except Exception as e: log.debug("save_principals(): %s", e, exc_info=True) ret = False return ret def save(self): obj = super(KerberosKeytabCreateForm, self).save() if not self.save_principals(obj): obj.delete() log.debug("save(): unable to save principals") notifier().start("ix-kerberos")
class GetSignatureForm(forms.Form): myFile = FileField(label='Song File')
class ImageForm(Form): file = FileField()
class TestingScriptForm(Form): """TestingScriptForm for the UI The TestingScriptForm accepts a test script from the settings page in the UI. This form handles accepting the file upload and setting the script_type to test if no script_script is set in the embedded YAML. The ScriptForm above validates the script itself. """ content = FileField(label="Test script", allow_empty_file=False) def __init__(self, instance=None, *args, **kwargs): super().__init__(*args, **kwargs) self._form = None def clean_content(self): content = self.cleaned_data["content"] script_name = content.name script_content = content.read().decode() try: script = Script.objects.get(name=script_name) except Script.DoesNotExist: form = ScriptForm(data={"script": script_content}) # If the form isn't valid due to the name it may be because the # embedded YAML doesn't define a name. Try again defining it. if not form.is_valid() and "name" in form.errors: form = ScriptForm(data={ "name": script_name, "script": script_content }) else: form = ScriptForm(data={"script": script_content}, instance=script) self._form = form return content def is_valid(self): valid = super().is_valid() # If content is empty self.clean_content isn't run. if self._form is not None and not self._form.is_valid(): # This form only has content so all errors must be on that field. if "content" not in self.errors: self.errors["content"] = [] for key, errors in self._form.errors.items(): for error in errors: self.errors["content"].append("%s: %s" % (key, error)) return False else: return valid def save(self, request, *args, **kwargs): script = self._form.save(*args, **kwargs, commit=False, request=request, endpoint=ENDPOINT.UI) # If the embedded script data did not set a script type, # set it to testing. if "script_type" not in self._form.data: script.script_type = SCRIPT_TYPE.TESTING script.save()
class DocumentsForm(Form): student_mailing = BooleanField() student_emailing = BooleanField() college_sending = BooleanField() cv_or_resume = FileField()
class ScheduleImportForm(Form): upload = FileField() class Meta: fields = ('upload', )
class UploadStaticForm(Form): file = FileField()
class ChangePinFileForm(Form): """ Cambio pin con upload del certificato """ oldPinField = CharField(widget=PasswordInput(attrs={'id': 'oldPinField', 'name': 'oldPinField'}), required=True, error_messages={'required': 'Campo obbligatorio!'}, validators=[regex_dim_pin]) newPinField = CharField(widget=PasswordInput(attrs={'id': 'newPinField', 'name': 'newPinField'}), required=True, error_messages={'required': 'Campo obbligatorio!'}, validators=[regex_dim_pin]) confirmPinField = CharField(widget=PasswordInput(attrs={'id': 'confirmPinField', 'name': 'confirmPinField'}), required=True, error_messages={'required': 'Campo obbligatorio!'}, validators=[regex_dim_pin]) uploadCertificate = FileField(required=True, error_messages={'required': 'Campo obbligatorio!'}, widget=FileInput( attrs={'id': 'uploadCertificate'})) uploadPrivateKey = FileField(required=True, error_messages={'required': 'Campo obbligatorio!'}, widget=FileInput( attrs={'id': 'uploadPrivateKey'})) formPin = None cert = None def clean_newPinField(self): self.formPin = self.cleaned_data.get('newPinField') if not self.formPin or (self.formPin and re.match(regex_pin, self.formPin)): raise ValidationError("Il pin non può avere cifre uguali o crescenti!") return def clean_confirmPinField(self): formConfirmPin = self.cleaned_data.get('confirmPinField') if not self.formPin or (self.formPin and self.formPin != formConfirmPin): raise ValidationError("I PIN non corrispondono!") return def clean_uploadCertificate(self): uploadCertificate = self.cleaned_data.get('uploadCertificate') if not uploadCertificate: raise ValidationError("Il certificato selezionato non è valido!") self.cert = get_certificate(uploadCertificate) if "BEGIN RSA PRIVATE KEY" in self.cert: self.cert = None LOG.error("Chiave privata presente - Certificato non valido", extra=set_client_ip()) raise ValidationError("Il certificato non deve contenere la chiave privata!") if not check_expiration_certificate(self.cert) or not verify_policy_certificate(self.cert): LOG.error("Policy del certificato non valide o certificato scaduto", extra=set_client_ip()) raise ValidationError("Il certificato selezionato non è valido!") result = verify_certificate_chain(self.cert) if result == StatusCode.ERROR.value: raise ValidationError("Il certificato selezionato non è valido!") if result == StatusCode.EXC.value or result == StatusCode.NOT_FOUND.value: raise ValidationError("Impossibile verificare il certificato selezionato!") return def clean_uploadPrivateKey(self): uploadPrivateKey = self.cleaned_data.get('uploadPrivateKey') if not self.cert: raise ValidationError("Devi prima caricare il certificato!") if not uploadPrivateKey: raise ValidationError("La chiave privata selezionata non è valida!") pk = get_certificate(uploadPrivateKey) if "BEGIN CERTIFICATE" in pk: LOG.error("Certificato presente - Chiave privata non valida", extra=set_client_ip()) raise ValidationError("La chiave privata non deve contenere il certificato!") cert = pk + "\n" + self.cert try: crypto.load_certificate(crypto.FILETYPE_PEM, cert.encode()) except Exception as e: LOG.error("Warning: {}".format(str(e)), extra=set_client_ip()) raise ValidationError("La chiave privata selezionata non è valida!") try: crypto.load_privatekey(crypto.FILETYPE_PEM, cert.encode()) except Exception as e: LOG.error("Warning: {}".format(str(e)), extra=set_client_ip()) raise ValidationError("La chiave privata selezionata non è valida!") return
class UploadFileForm(Form): file = FileField()
def _create_file_field(self, options): if self.cde.allow_multiple: return fields.MultipleFileField(**options) else: return FileField(**options)
class ImportForm(Form): file = FileField()
class PBIUploadForm(Form): pbifile = FileField( label=_("PBI file to be installed"), help_text=_("Click here to find out what PBI's are!" "<a href='http://www.pcbsd.org/en/package-management/' " "onclick='window.open(this.href);return false;'>"), required=True) def __init__(self, *args, **kwargs): self.jail = None if kwargs and 'jail' in kwargs: self.jail = kwargs.pop('jail') super(PBIUploadForm, self).__init__(*args, **kwargs) if self.jail: self.fields['pjail'] = forms.ChoiceField( label=_("Plugin Jail"), help_text=_( "The plugin jail that the PBI is to be installed in."), choices=((self.jail.jail_host, self.jail.jail_host), ), widget=forms.Select( attrs={ 'class': ('requireddijitDisabled dijitTextBoxDisabled ' 'dijitValidationTextBoxDisabled'), 'readonly': True, }), required=False, ) def clean(self): cleaned_data = self.cleaned_data filename = '/var/tmp/firmware/pbifile.pbi' if cleaned_data.get('pbifile'): if hasattr(cleaned_data['pbifile'], 'temporary_file_path'): shutil.move(cleaned_data['pbifile'].temporary_file_path(), filename) else: with open(filename, 'wb+') as sp: for c in cleaned_data['pbifile'].chunks(): sp.write(c) else: self._errors["pbifile"] = self.error_class([ _("This field is required."), ]) return cleaned_data def done(self, *args, **kwargs): newplugin = [] pjail = self.cleaned_data.get('pjail') jail = None if not pjail: #FIXME: Better base name, using pbi_info jail = new_default_plugin_jail("customplugin") pjail = jail.jail_host if notifier().install_pbi(pjail, newplugin): newplugin = newplugin[0] notifier()._restart_plugins( newplugin.plugin_jail, newplugin.plugin_name, ) elif jail: jail.delete()
class BatchForm(ModelForm): csv_file = FileField(label='CSV File') # Allow a form to be submitted without an 'allotted_assignment_time' # field. The default value for this field will be used instead. # See also the function clean_allotted_assignment_time(). allotted_assignment_time = IntegerField(initial=Batch._meta.get_field( 'allotted_assignment_time').get_default(), required=False) def __init__(self, *args, **kwargs): super(BatchForm, self).__init__(*args, **kwargs) self.fields[ 'allotted_assignment_time'].label = 'Allotted assignment time (hours)' self.fields['allotted_assignment_time'].help_text = 'If a user abandons a Task, ' + \ 'this determines how long it takes until their assignment is deleted and ' + \ 'someone else can work on the Task.' self.fields['csv_file'].help_text = 'You can Drag-and-Drop a CSV file onto this ' + \ 'window, or use the "Choose File" button to browse for the file' self.fields['csv_file'].widget = CustomButtonFileWidget() self.fields['project'].label = 'Project' self.fields['name'].label = 'Batch Name' # csv_file field not required if changing existing Batch # # When changing a Batch, the BatchAdmin.get_fields() # function will cause the form to be rendered without # displaying an HTML form field for the csv_file field. I was # running into strange behavior where Django would still try # to validate the csv_file form field, even though there was # no way for the user to provide a value for this field. The # two lines below prevent this problem from occurring, by # making the csv_file field optional when changing # a Batch. if not self.instance._state.adding: self.fields['csv_file'].required = False self.fields['project'].widget = \ ProjectNameReadOnlyWidget(self.instance.project) def clean(self): """Verify format of CSV file Verify that: - fieldnames in CSV file are identical to fieldnames in Project - number of fields in each row matches number of fields in CSV header """ cleaned_data = super(BatchForm, self).clean() csv_file = cleaned_data.get("csv_file", False) project = cleaned_data.get("project") if not csv_file or not project: return validation_errors = [] rows = unicodecsv.reader(csv_file) header = next(rows) csv_fields = set(header) template_fields = set(project.fieldnames) if csv_fields != template_fields: template_but_not_csv = template_fields.difference(csv_fields) if template_but_not_csv: validation_errors.append( ValidationError( 'The CSV file is missing fields that are in the HTML template. ' 'These missing fields are: %s' % ', '.join(template_but_not_csv))) expected_fields = len(header) for (i, row) in enumerate(rows): if len(row) != expected_fields: validation_errors.append( ValidationError( 'The CSV file header has %d fields, but line %d has %d fields' % (expected_fields, i + 2, len(row)))) if validation_errors: raise ValidationError(validation_errors) # Rewind file, so it can be re-read csv_file.seek(0) def clean_allotted_assignment_time(self): """Clean 'allotted_assignment_time' form field - If the allotted_assignment_time field is not submitted as part of the form data (e.g. when interacting with this form via a script), use the default value. - If the allotted_assignment_time is an empty string (e.g. when submitting the form using a browser), raise a ValidationError """ data = self.data.get('allotted_assignment_time') if data is None: return Batch._meta.get_field( 'allotted_assignment_time').get_default() elif data.strip() is u'': raise ValidationError('This field is required.') else: return data
class UploadLocalFileForm(forms.Form): op = "upload" file = FileField(label=_("File to Upload"))
class UploadArchiveForm(forms.Form): op = "upload" archive = FileField(forms.Form, label=_("Archive to Upload")) dest = PathField(label=_("Destination Path"), help_text=_("Archive to upload to."))
class ImageConverterForm(Form): """ A simple for that merely provides a FileField. """ file = FileField(label='', help_text='')
class AssetImportForm(Form): assets_csv = FileField()
def create_document_field(self, field, options): return FileField(**options)
class FileForm(Form): file1 = FileField()
def test_filefield_3(self): f = FileField(allow_empty_file=True) self.assertIsInstance(f.clean(SimpleUploadedFile('name', b'')), SimpleUploadedFile)
class UserPerfilForm(ModelForm): clave_rh = CharField( label="Clave de empleado:", widget=TextInput( attrs={'class': 'form-control input-xs', 'readonly': 'True'} ) ) clave_jde = CharField( label="Clave de JDE:", widget=TextInput( attrs={'class': 'form-control input-xs', 'readonly': 'True'} ) ) fecha_nacimiento = CharField( label='Fecha de nacimiento', widget=DateInput( attrs={'class': 'form-control input-xs', 'data-date-format': 'yyyy-mm-dd', 'readonly': 'True'} ), ) foto = FileField( label="Foto", widget=ClearableFileInput( attrs={'class': 'dropzone dz-clickable dz-started'} ), ) class Meta: model = User fields = [ 'first_name', 'last_name', 'email', 'clave_rh', 'clave_jde', 'fecha_nacimiento', 'foto', ] labels = { 'first_name': 'Nombre', 'last_name': 'Apellidos', 'email': 'Email', 'clave_rh': 'Clave de empleado', 'clave_jde': 'Clave de JDE', 'fecha_nacimiento': 'Fecha de nacimiento', 'foto': 'Foto', } widgets = { 'first_name': TextInput(attrs={'class': 'form-control input-xs', 'readonly': 'True'}), 'last_name': TextInput(attrs={'class': 'form-control input-xs', 'readonly': 'True'}), 'email': TextInput(attrs={'class': 'form-control input-xs'}), } def __init__(self, *args, **kwargs): super(UserPerfilForm, self).__init__(*args, **kwargs) self.fields['clave_jde'].required = False self.fields['fecha_nacimiento'].required = False self.fields['foto'].required = False
def test_disabled_has_changed(self): f = FileField(disabled=True) self.assertIs(f.has_changed('x', 'y'), False)
class EDRImportForm(Form): csv = FileField(required=True) is_state_companies = BooleanField( required=False, help_text="Керівники усіх компанії з файлу є ПЕПами")
class UploadConfigForm(Form): config_file = FileField()
class ForeignImportForm(Form): csv = FileField(required=True)
class ZIPImportForm(Form): zipfile = FileField(required=True, label="ZIP-файл")
def test_filefield_1(self): f = FileField() with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean('') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean('', '') self.assertEqual('files/test1.pdf', f.clean('', 'files/test1.pdf')) with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean(None) with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean(None, '') self.assertEqual('files/test2.pdf', f.clean(None, 'files/test2.pdf')) no_file_msg = "'No file was submitted. Check the encoding type on the form.'" with self.assertRaisesMessage(ValidationError, no_file_msg): f.clean(SimpleUploadedFile('', b'')) with self.assertRaisesMessage(ValidationError, no_file_msg): f.clean(SimpleUploadedFile('', b''), '') self.assertEqual('files/test3.pdf', f.clean(None, 'files/test3.pdf')) with self.assertRaisesMessage(ValidationError, no_file_msg): f.clean('some content that is not a file') with self.assertRaisesMessage(ValidationError, "'The submitted file is empty.'"): f.clean(SimpleUploadedFile('name', None)) with self.assertRaisesMessage(ValidationError, "'The submitted file is empty.'"): f.clean(SimpleUploadedFile('name', b'')) self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', b'Some File Content')))) self.assertIsInstance( f.clean(SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', 'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह'.encode())), SimpleUploadedFile ) self.assertIsInstance( f.clean(SimpleUploadedFile('name', b'Some File Content'), 'files/test4.pdf'), SimpleUploadedFile )
class WorkshopForm(ModelForm): class CategoryChoiceField(ModelMultipleChoiceField): def label_from_instance(self, obj): return obj.name class TypeChoiceField(ModelChoiceField): def label_from_instance(self, obj): return obj.name # Note that the querysets for category and type are overwritten in __init__, but the argument is required here category = CategoryChoiceField( label="Kategorie", queryset=WorkshopCategory.objects.all(), widget=Select2MultipleWidget(attrs={'width': '200px'})) type = TypeChoiceField(label="Rodzaj zajęć", queryset=WorkshopType.objects.all(), widget=Select2Widget(attrs={'width': '200px'})) qualification_problems = FileField( required=False, widget=FileInput(), label='Zadania kwalifikacyjne (wymagany format PDF):', validators=[FileExtensionValidator(allowed_extensions=['pdf'])]) class Meta: model = Workshop fields = [ 'title', 'name', 'type', 'category', 'proposition_description', 'qualification_problems', 'is_qualifying', 'solution_uploads_enabled', 'max_points', 'qualification_threshold', 'short_description', 'page_content', 'page_content_is_public' ] labels = { 'title': 'Tytuł', 'name': 'Nazwa (w URLach)', 'proposition_description': 'Opis propozycji warsztatów', 'is_qualifying': 'Czy warsztaty są kwalifikujące', 'solution_uploads_enabled': 'Czy przesyłanie rozwiązań przez stronę jest włączone', 'max_points': 'Maksymalna liczba punktów możliwa do uzyskania', 'qualification_threshold': 'Minimalna liczba punktów potrzebna do kwalifikacji', 'short_description': 'Krótki opis warsztatów', 'page_content': 'Strona warsztatów', 'page_content_is_public': 'Zaznacz, jeśli opis jest gotowy i może już być publiczny.' } help_texts = { 'short_description': 'Zachęć uczestnika do zainteresowania się Twoimi warsztatami w max 140 znakach. Wyświetlany na stronie z programem.', 'is_qualifying': '(odznacz, jeśli nie zamierzasz dodawać zadań i robić kwalifikacji)', 'solution_uploads_enabled': 'Od edycji 2021 uczestnicy przesyłają rozwiązania zadań kwalifikacyjnych przez stronę zamiast maila. Jeśli z jakiegoś powodu bardzo chcesz wyłączyć tą funkcję, skontaktuj się z organizatorami.', 'qualification_threshold': '(wpisz dopiero po sprawdzeniu zadań)', 'max_points': '(możesz postawić punkty bonusowe powyżej tej wartości, ale tylko do max. {}%)' .format(settings.MAX_POINTS_PERCENT) } def __init__(self, *args, workshop_url, has_perm_to_edit=True, has_perm_to_disable_uploads=False, profile_warnings=None, **kwargs): super(ModelForm, self).__init__(*args, **kwargs) self.helper = FormHelper(self) self.helper.include_media = False # Disable fields that should be disabled if not self.instance.is_workshop_editable() or not has_perm_to_edit: for field in self.fields.values(): field.disabled = True if self.instance.status: # The proposition cannot be edited once the workshop has a status set self.fields['proposition_description'].disabled = True if not has_perm_to_disable_uploads: self.fields['solution_uploads_enabled'].disabled = True # Make sure only current category and type choices are displayed if self.instance is None: raise ValueError( 'WorkshopForm must be provided with an instance with the .year field already set' ) year = self.instance.year self.fields['category'].queryset = WorkshopCategory.objects.filter( year=year) self.fields['type'].queryset = WorkshopType.objects.filter(year=year) # Display link to current qualification tasks: if self.instance.qualification_problems: self.fields['qualification_problems'].help_text = format_html( 'Aktualnie: <a href="{}" target="_blank">{}</a>', reverse('qualification_problems', args=[self.instance.year.pk, self.instance.name]), os.path.basename(self.instance.qualification_problems.path)) else: self.fields['qualification_problems'].help_text = 'Aktualnie: brak' # Configure TinyMCE settings mce_attrs = {} mce_attrs['readonly'] = self.fields[ 'proposition_description'].disabled # does not seem to respect the Django field settings for some reason self.fields['proposition_description'].widget = InitializedTinyMCE( mce_attrs=mce_attrs) mce_attrs = settings.TINYMCE_DEFAULT_CONFIG_WITH_IMAGES.copy() if self.instance and self.instance.pk: mce_attrs['automatic_uploads'] = True mce_attrs['images_upload_url'] = reverse('workshop_edit_upload', kwargs={ 'year': self.instance.year.pk, 'name': self.instance.name }) mce_attrs['readonly'] = self.fields[ 'page_content'].disabled # does not seem to respect the Django field settings for some reason self.fields['page_content'].widget = InitializedTinyMCE( mce_attrs=mce_attrs) # Layout self.fieldset_general = Fieldset( "Ogólne", Div(Div(PrependedAppendedText( 'name', workshop_url[0] + '<b>' + str(year.pk) + '</b>' + workshop_url[1], workshop_url[2], template= "%s/layout/prepended_appended_text_with_mobile_support.html"), css_class='col-lg-12'), Div('title', css_class='col-lg-12'), css_class='row'), Div(Div('type', css_class='col-lg-6'), Div('category', css_class='col-lg-6'), css_class='row'), ) if profile_warnings: for message in profile_warnings: self.fieldset_general.fields.append( Alert(content=message, dismiss=False, css_class='alert-info')) self.fieldset_proposal = Fieldset( "Opis propozycji", 'proposition_description', ) self.fieldset_qualification = Fieldset( "Kwalifikacja", 'is_qualifying', Div('qualification_problems', Div(Div('max_points', css_class='col-lg-6'), Div('qualification_threshold', css_class='col-lg-6'), css_class='row'), 'solution_uploads_enabled', css_id='qualification_settings'), ) self.fieldset_public_page = Fieldset("Strona warsztatów", 'short_description', 'page_content', 'page_content_is_public') self.fieldset_submit = FormActions( StrictButton( 'Zapisz' if self.instance and self.instance.pk else 'Zgłoś!', type='submit', css_class='btn-outline-primary btn-lg mx-1 my-3'), css_class='text-right', ) if not self.instance or not self.instance.is_publicly_visible(): for field in [ 'qualification_problems', 'is_qualifying', 'solution_uploads_enabled', 'max_points', 'qualification_threshold', 'short_description', 'page_content', 'page_content_is_public' ]: del self.fields[field] self.helper.layout = Layout( self.fieldset_general, self.fieldset_proposal, self.fieldset_submit, ) else: if not has_perm_to_edit: self.helper.layout = Layout( self.fieldset_general, self.fieldset_proposal, self.fieldset_qualification, self.fieldset_public_page, ) else: self.helper.layout = Layout( self.fieldset_general, self.fieldset_proposal, self.fieldset_qualification, self.fieldset_public_page, self.fieldset_submit, ) def clean(self): super(WorkshopForm, self).clean() if not self.instance.is_workshop_editable(): raise ValidationError( 'Nie można edytować warsztatów z poprzednich lat') def validate_unique(self): # Must remove year field from exclude in order # for the unique_together constraint to be enforced. exclude = self._get_validation_exclusions() exclude.remove('year') try: self.instance.validate_unique(exclude=exclude) except ValidationError as e: self._update_errors(e.message_dict)