class AppForm(TranslatableModelForm): screenshots = ImageField(required=False, widget=ClearableFileInput(attrs={'multiple': True})) apks = FileField(required=False, widget=ClearableFileInput(attrs={'multiple': True})) def __init__(self, *args, **kwargs): super(AppForm, self).__init__(*args, **kwargs) if self.instance.category: # Show only own and default categories self.fields['category'].queryset = Category.objects.filter( Q(user=None) | Q(user=self.instance.repo.user)) def save(self, commit=True): # remove old feature graphic if there was one if 'feature_graphic' in self.initial and self.initial['feature_graphic'].name \ and 'feature_graphic' in self.changed_data: old_graphic = self.initial['feature_graphic'].path if os.path.exists(old_graphic): os.remove(old_graphic) return super().save(commit) class Meta: model = App fields = ['summary', 'summary_override', 'description', 'description_override', 'author_name', 'website', 'category', 'screenshots', 'feature_graphic', 'apks'] widgets = {'description': MDLTinyMCE(), 'description_override': MDLTinyMCE()}
def test_html_escaped(self): """ A ClearableFileInput should escape name, filename, and URL when rendering HTML (#15182). """ @python_2_unicode_compatible class StrangeFieldFile(object): url = "something?chapter=1§=2©=3&lang=en" def __str__(self): return '''something<div onclick="alert('oops')">.jpg''' widget = ClearableFileInput() field = StrangeFieldFile() output = widget.render('my<div>file', field) self.assertNotIn(field.url, output) self.assertIn( 'href="something?chapter=1&sect=2&copy=3&lang=en"', output) self.assertNotIn(six.text_type(field), output) self.assertIn( 'something<div onclick="alert('oops')">.jpg', output) self.assertIn('my<div>file', output) self.assertNotIn('my<div>file', output)
class Meta: model = ObjectiveOptionModel fields = '__all__' widgets = { 'Option_Image': ClearableFileInput(attrs={'multiple': True}), 'Option_Audio': ClearableFileInput(attrs={'multiple': True}), 'Option_Video': ClearableFileInput(attrs={'multiple': True}), }
def test_value_omitted_from_data(self): widget = ClearableFileInput() self.assertIs(widget.value_omitted_from_data({}, {}, "field"), True) self.assertIs( widget.value_omitted_from_data({}, {"field": "x"}, "field"), False) self.assertIs( widget.value_omitted_from_data({"field-clear": "y"}, {}, "field"), False)
def test_value_omitted_from_data(self): widget = ClearableFileInput() self.assertIs(widget.value_omitted_from_data({}, {}, 'field'), True) self.assertIs( widget.value_omitted_from_data({}, {'field': 'x'}, 'field'), False) self.assertIs( widget.value_omitted_from_data({'field-clear': 'y'}, {}, 'field'), False)
def test_render_custom_template(self): widget = ClearableFileInput() widget.template_with_initial = ( '%(initial_text)s: <img src="%(initial_url)s" alt="%(initial)s" /> ' '%(clear_template)s<br />%(input_text)s: %(input)s') self.assertHTMLEqual( widget.render('myfile', FakeFieldFile()), 'Currently: <img src="something" alt="something" /> ' '<input type="checkbox" name="myfile-clear" id="myfile-clear_id" /> ' '<label for="myfile-clear_id">Clear</label><br />Change: <input type="file" name="myfile" />' )
def test_clear_input_checked_returns_false_only_if_not_required(self): """ ClearableFileInput.value_from_datadict never returns False if the field is required. """ widget = ClearableFileInput() widget.is_required = True field = SimpleUploadedFile("something.txt", b"content") value = widget.value_from_datadict(data={"myfile-clear": True}, files={"myfile": field}, name="myfile") self.assertEqual(value, field)
def test_render_custom_template(self): widget = ClearableFileInput() widget.template_with_initial = ( '%(initial_text)s: <img src="%(initial_url)s" alt="%(initial)s" /> ' '%(clear_template)s<br />%(input_text)s: %(input)s' ) self.assertHTMLEqual( widget.render('myfile', FakeFieldFile()), 'Currently: <img src="something" alt="something" /> ' '<input type="checkbox" name="myfile-clear" id="myfile-clear_id" /> ' '<label for="myfile-clear_id">Clear</label><br />Change: <input type="file" name="myfile" />' )
def test_clear_input_renders_only_if_not_required(self): """ A ClearableFileInput with is_required=False does not render a clear checkbox. """ widget = ClearableFileInput() widget.is_required = True self.check_html(widget, 'myfile', FakeFieldFile(), html=( """ Currently: <a href="something">something</a> <br /> Change: <input type="file" name="myfile" /> """ ))
def test_clear_input_renders_only_if_not_required(self): """ A ClearableFileInput with is_required=False does not render a clear checkbox. """ widget = ClearableFileInput() widget.is_required = True self.check_html(widget, 'myfile', FakeFieldFile(), html=( """ Currently: <a href="something">something</a> <br> Change: <input type="file" name="myfile"> """ ))
def test_build_attr(self): assert set(ClearableFileInput().build_attrs({}).keys()) == { "class", "data-url", "data-fields-x-amz-algorithm", "data-fields-x-amz-date", "data-fields-x-amz-signature", "data-fields-x-amz-credential", "data-fields-policy", "data-fields-key", } assert ClearableFileInput().build_attrs({})["class"] == "s3file" assert (ClearableFileInput().build_attrs( {"class": "my-class"})["class"] == "my-class s3file")
def test_build_attr(self): assert set(ClearableFileInput().build_attrs({}).keys()) == { 'class', 'data-url', 'data-fields-x-amz-algorithm', 'data-fields-x-amz-date', 'data-fields-x-amz-signature', 'data-fields-x-amz-credential', 'data-fields-policy', 'data-fields-key', } assert ClearableFileInput().build_attrs({})['class'] == 's3file' assert ClearableFileInput().build_attrs( {'class': 'my-class'})['class'] == 'my-class s3file'
def test_clear_input_checked_returns_false_only_if_not_required(self): """ ClearableFileInput.value_from_datadict never returns False if the field is required. """ widget = ClearableFileInput() widget.is_required = True field = SimpleUploadedFile('something.txt', b'content') value = widget.value_from_datadict( data={'myfile-clear': True}, files={'myfile': field}, name='myfile', ) self.assertEqual(value, field)
class Meta: model = Post fields = ( 'title', 'image', 'content', 'status', ) widgets = { 'title': TextInput(attrs={'class': 'form-control'}), 'image': ClearableFileInput( attrs={ 'class': 'filestyle', 'data-buttonText': "Seleccionar Imagen", 'data-iconName': "glyphicon glyphicon-picture" }), 'content': Textarea(attrs={ 'class': 'form-control', 'rows': '8' }), 'status': Select(attrs={'class': 'form-control'}), } labels = { 'title': 'Titulo de la publicacion', 'image': 'Portada', 'content': 'Contenido', 'status': 'Estado', }
class Meta: model = Contact fields = ['listName','businessName','contactName','address1', 'address2','address3','address4','postCode', 'telephone','mobile','fax','email', 'website','categories','notes','picture'] widgets = { 'listName': TextInput(attrs={'class':'form-control','id':'listName','name':'listName','required':'','data-error':'Debe ingresar el Nombre de Lista'}), 'businessName': TextInput(attrs={'class':'form-control','id':'businessName','name':'businessName'}), 'contactName': TextInput(attrs={'class':'form-control','id':'contactName','name':'contactName','required':''}), 'address1': TextInput(attrs={'class':'form-control','id':'address1','name':'address1','required':''}), 'address2': TextInput(attrs={'class':'form-control','id':'address2','name':'address2'}), 'address3': TextInput(attrs={'class':'form-control','id':'address3','name':'address3'}), 'address4': TextInput(attrs={'class':'form-control','id':'address4','name':'address4'}), 'postCode': TextInput(attrs={'class':'form-control','id':'postCode','name':'postCode'}), 'telephone': TextInput(attrs={'class':'form-control','id':'telephone','name':'telephone'}), 'mobile': TextInput(attrs={'class':'form-control','id':'mobile','name':'mobile'}), 'fax': TextInput(attrs={'class':'form-control','id':'fax','name':'fax'}), 'email': EmailInput(attrs={'class':'form-control','id':'email','name':'email'}), 'website': URLInput(attrs={'class':'form-control','id':'website','name':'website'}), 'categories': RadioSelect(attrs={'class':'radio','id':'categories','name':'categories'}), 'notes': Textarea(attrs={'class':'form-control','id':'notes','name':'notes','rows':'8'}), 'picture': ClearableFileInput(attrs={'name':'picture','id':'picture','style':'height:35px;'}) }
class Meta: model = Member fields = [ 'type', 'first_name', 'last_name', 'birth_date', 'address', 'city', 'postal_code', 'phone_number', 'email', 'emergency_contact', 'emergency_phone_number', 'stripe_customer_code', 'brief_notes', 'photo' ] labels = { 'birth_date': 'Birthdate (MM/DD/YYYY)', 'stripe_customer_code': 'Stripe customer code (Leave blank if none)', 'brief_notes': 'Notes (keep it brief - 200 characters max)' } widgets = { 'type': Select(attrs={'class': 'form-control'}), 'first_name': TextInput(attrs={'class': 'form-control'}), 'last_name': TextInput(attrs={'class': 'form-control'}), 'birth_date': DateInput(attrs={'class': 'form-control datepicker'}), 'address': TextInput(attrs={'class': 'form-control'}), 'city': TextInput(attrs={'class': 'form-control'}), 'postal_code': TextInput(attrs={'class': 'form-control'}), 'phone_number': TextInput(attrs={'class': 'form-control'}), 'email': TextInput(attrs={'class': 'form-control'}), 'emergency_contact': TextInput(attrs={'class': 'form-control'}), 'emergency_phone_number': TextInput(attrs={'class': 'form-control'}), 'stripe_customer_code': TextInput(attrs={'class': 'form-control'}), 'brief_notes': TextInput(attrs={'class': 'form-control'}), 'photo': ClearableFileInput(attrs={'class': 'form-control'}), }
class GalleryAdminForm(TranslatableModelForm): #region -----Information----- images=FileField(label=_("Add images"), required=False, widget=ClearableFileInput(attrs={"multiple": True})) #endregion #region -----Internal Methods----- def save_images(self, gallery: Gallery)->None: """ Associates selected images with gallery\n :param gallery: gallery class instance\n @return None """ [Image(gallery=gallery, large_image=image).save() for image in self.files.getlist("images")] def validate_image_extensions(self)->None: """ Validates image file extensions and can raise exception if format is invalid\n @return None """ [validate_image_file_extension(value=image) for image in self.files.getlist("images")] #endregion #region -----Metadata----- class Meta(object): fields=["title", "description"] model=Gallery
class UserProfileForm(ModelForm): icon = FileField( widget=ClearableFileInput(attrs={ 'multiple': False, 'style': 'display: none;', 'accept': 'image/*' }), required=False) class Meta: custom_themes = [ ('bootstrap.default.min.css', 'Default'), ('bootstrap.cerulean.min.css', 'Cerulean'), ('bootstrap.darkly.min.css', 'Darkly'), ('bootstrap.litera.min.css', 'Litera'), ('bootstrap.spacelab.min.css', 'Spacelab'), ] model = UserProfile exclude = ('user', 'password_changed', 'favourite_projects', 'favourite_credentials') widgets = { 'favourite_menu': CheckboxInput(attrs={'class': 'custom-control-input'}), 'favourite_tags': SelectMultiple(attrs={'class': 'single-select'}), 'theme': Select(choices=custom_themes, attrs={'class': 'form-control single-select'}), 'items_per_page': Select(choices=[('10', 10), ('20', 20), ('30', 30), ('40', 40), ('50', 50)], attrs={'class': 'form-control single-select'}), }
class NuevaSolicitudForm(Form): asunto = ChoiceField( label="Asunto", widget=Select(attrs={'class': 'select2 nova-select2'})) descripcion = CharField( label="Descripcion", widget=Textarea( attrs={ 'class': 'form-control input-xs', 'placeholder': 'Ejemplo: Se detectaron incosistencias en la informacion...', 'rows': '5' })) archivo = FileField(label="Archivos", widget=ClearableFileInput( attrs={ 'class': 'dropzone dz-clickable dz-started', 'type': 'file', 'multiple': True })) def __init__(self, *args, **kwargs): super(NuevaSolicitudForm, self).__init__(*args, **kwargs) self.fields['asunto'].choices = self.get_Asuntos() def get_Asuntos(self): valores = [('', '------------')] asuntos = Asunto.objects.all() for asunto in asuntos: valores.append((asunto.pk, asunto.nombre)) return valores
class Meta: model = Creator fields = ( "name", "desc", "alias", "birth", "death", "image", ) widgets = { "name": TextInput(attrs={"class": "input"}), "desc": Textarea(attrs={"class": "textarea"}), "alias": TextInput(attrs={"class": "input"}), "birth": DateInput(attrs={ "class": "input", "type": "date" }, ), "death": DateInput(attrs={ "class": "input", "type": "date" }, ), "image": ClearableFileInput(), } help_texts = { "alias": "Separate multiple aliases by a comma", }
class Meta: model = UploadModel fields = ['files'] widgets = { "files": ClearableFileInput(attrs={'multiple': True}), } labels = {"files": ""}
def test_html_escaped(self): """ A ClearableFileInput should escape name, filename, and URL when rendering HTML (#15182). """ class StrangeFieldFile: url = "something?chapter=1§=2©=3&lang=en" def __str__(self): return """something<div onclick="alert('oops')">.jpg""" self.check_html( ClearableFileInput(), "my<div>file", StrangeFieldFile(), html=( """ Currently: <a href="something?chapter=1&sect=2&copy=3&lang=en"> something<div onclick="alert('oops')">.jpg</a> <input type="checkbox" name="my<div>file-clear" id="my<div>file-clear_id"> <label for="my<div>file-clear_id">Clear</label><br> Change: <input type="file" name="my<div>file"> """ ), )
class Meta: model = GraphiCards fields = ('name','file_name', 'Rep','Quantity','Price', ) widgets = { 'name': TextInput(attrs={ 'class': "form-control", 'style': 'max-width: 300px;', 'placeholder': 'name' }), 'file_name': TextInput(attrs={ 'class': "form-control", 'style': 'max-width: 300px;', 'placeholder': 'file_name' }), 'Rep': ClearableFileInput(attrs={ 'class': "form-control", 'style': 'max-width: 300px;', 'placeholder': 'file path' }), 'Quantity': NumberInput(attrs={ 'class': "form-control", 'style': 'max-width: 300px;', 'placeholder': 'Quantity' }), 'Price': NumberInput(attrs={ 'class': "form-control", 'style': 'max-width: 300px;', 'placeholder': 'Price' }) }
class Meta: model = PostFile fields = ['file'] widgets = { 'file': ClearableFileInput(attrs={'multiple': True}), } labels = {'file': 'Property Photo'}
class ApkForm(BaseModelForm): apks = FileField(required=False, widget=ClearableFileInput(attrs={'multiple': True})) class Meta: model = Apk fields = ['apks']
class PhotoForm(ModelForm): """ Classe qui permet la création d'un formulaire pour uploader une(des) photo(s) """ fichier = FileField(widget=ClearableFileInput(attrs={"multiple": True})) date_de_l_evenement = DateField(required=True, input_formats=DATE_INPUTS_FORMATS) # utiliser plutôt l'attribut label comme pour AbonnementEvenementForm # ================================== def __init__(self, *args, **kwargs): """ Constructeur de la classe """ # Les lignes suivantes permettent de modifier les label d'un champ dans la page super(ModelForm, self).__init__(*args, **kwargs) self.fields["nom_de_l_evenement"].label = "Nom de l'évènement" self.fields["date_de_l_evenement"].label = "Date de l'évènement" # utiliser plutôt l'attribut label comme pour AbonnementEvenementForm self.fields["fichier"].label = "Photo(s)" # ========= class Meta: """ Configuration/définition des options de metadonnées du formulaire """ model = Photo fields = ("fichier", "nom_de_l_evenement", "date_de_l_evenement")
class CoffeeMeetingFeedForm(ModelForm): class Meta: model = CoffeeMeetingFeed fields = ['content', 'coffee_meeting'] images = forms.FileField(widget=ClearableFileInput(attrs={'multiple': True}), label='커모 후기 사진') def __init__(self, *args, **kwargs): self.author = kwargs.pop('author', None) self.coffee_meeting = kwargs.pop('coffee_meeting', None) self.participants = kwargs.pop('participants', None) # 업데이트시 participants를 추가해준다. if self.participants is None: self.participants = kwargs['instance'].coffee_meeting.list_participants() super(CoffeeMeetingFeedForm, self).__init__(*args, **kwargs) # 커모는 바꾸면 안되겠지 self.fields['coffee_meeting'].initial = self.coffee_meeting self.fields['coffee_meeting'].widget.attrs['readonly'] = True self.fields['participants'] = MultipleChoiceField(label='참가자', help_text='참가하지 못한 사람은 꼭 <b>체크를 해제</b>해주세요!', choices=[(participant.pk, participant) for participant in self.participants], initial=[participant.pk for participant in self.participants], widget=CheckboxSelectMultiple) def clean_coffee_meeting(self): # 항상 넘어온 커모를 리턴한다 return self.coffee_meeting def save(self, commit=True): instance = super(CoffeeMeetingFeedForm, self).save(commit=False) instance.author = self.author instance.save() return instance
def test_widget_attrs_default_accept(self): f = ImageField() # Nothing added for non-FileInput widgets. self.assertEqual(f.widget_attrs(Widget()), {}) self.assertEqual(f.widget_attrs(FileInput()), {'accept': 'image/*'}) self.assertEqual(f.widget_attrs(ClearableFileInput()), {'accept': 'image/*'}) self.assertWidgetRendersTo(f, '<input type="file" name="f" accept="image/*" required id="id_f" />')
class EditUserForm(ModelForm): icon = FileField( widget=ClearableFileInput(attrs={ 'multiple': False, 'style': 'display: none;', 'accept': 'image/*' }), required=False) class Meta: model = User fields = [ 'username', 'email', 'is_staff', 'is_active', 'groups', 'icon' ] widgets = { 'username': TextInput(attrs={'class': 'form-control'}), 'email': TextInput(attrs={'class': 'form-control'}), 'is_staff': CheckboxInput(attrs={'class': 'custom-control-input'}), 'is_active': CheckboxInput(attrs={'class': 'custom-control-input'}), 'groups': SelectMultiple(attrs={'class': 'form-control single-select'}), } def clean(self): addvalidator = True
class Meta: model = Profile fields = ('avatar', 'mobile', 'weibo', 'wechat', 'facebook', 'twitter', 'instagram', 'telegram') error_messages = { 'avatar': { 'required': '请上传头像' }, } widgets = { 'avatar': ClearableFileInput(attrs={ 'class': 'form-control', 'placeholder': "头像" }), 'mobile': TextInput(attrs={'class': 'form-control'}), 'weibo': TextInput(attrs={'class': 'form-control'}), 'wechat': TextInput(attrs={'class': 'form-control'}), 'facebook': TextInput(attrs={'class': 'form-control'}), 'twitter': TextInput(attrs={'class': 'form-control'}), 'instagram': TextInput(attrs={'class': 'form-control'}), 'telegram': TextInput(attrs={'class': 'form-control'}), }
class Meta: model = Board fields = ['name', 'thumb', 'description'] widgets = { 'name': Textarea( attrs={ 'id': 'post-textarea-small', 'placeholder': 'Enter the name of your board.' } ), 'thumb': ClearableFileInput( attrs={ 'id': 'image-upload-button' } ), 'description': Textarea( attrs={ 'id': 'post-textarea', 'placeholder': 'Enter a description for your board.' } ) } labels = { 'name': '', 'thumb': 'Attach an Image (Optional)', 'description': '' }
class Meta: model = Post fields = ['content', 'thumb', 'video'] widgets = { 'content': Textarea( attrs={ 'id': 'post-textarea', 'placeholder': 'Start typing your thoughts here...' } ), 'thumb': ClearableFileInput( attrs={ 'id': 'image-upload-button' } ), 'video': Textarea( attrs={ 'id': 'post-textarea-small', 'placeholder': 'Add a link to a YouTube video or SoundCloud song (optional)...' } ) } labels = { 'content': '', 'thumb': 'Attach an Image (Optional)', 'video': '' }
class SolicitudesEditarForm(Form): STATUS = ( ('cap', 'En captura'), ('act', 'Actualizado'), ('rech', 'Rechazado'), ) observaciones = CharField(label="Observaciones:", widget=Textarea(attrs={ 'class': 'form-control input-xs', 'rows': '4' })) status_editar = ChoiceField( label="Estatus", choices=STATUS, widget=Select(attrs={'class': 'select2 nova-select2'})) archivo = FileField(label="Archivo", widget=ClearableFileInput( attrs={ 'class': 'dropzone dz-clickable dz-started', 'type': 'file', 'multiple': True })) def __init__(self, *args, **kwargs): super(SolicitudesEditarForm, self).__init__(*args, **kwargs) self.fields['observaciones'].required = False
def test_html_does_not_mask_exceptions(self): """ A ClearableFileInput should not mask exceptions produced while checking that it has a value. """ @python_2_unicode_compatible class FailingURLFieldFile(object): @property def url(self): raise RuntimeError('Canary') def __str__(self): return 'value' widget = ClearableFileInput() field = FailingURLFieldFile() with self.assertRaisesMessage(RuntimeError, 'Canary'): widget.render('myfile', field)
def test_html_escaped(self): """ A ClearableFileInput should escape name, filename, and URL when rendering HTML (#15182). """ @python_2_unicode_compatible class StrangeFieldFile(object): url = "something?chapter=1§=2©=3&lang=en" def __str__(self): return '''something<div onclick="alert('oops')">.jpg''' widget = ClearableFileInput() field = StrangeFieldFile() output = widget.render('my<div>file', field) self.assertNotIn(field.url, output) self.assertIn('href="something?chapter=1&sect=2&copy=3&lang=en"', output) self.assertNotIn(six.text_type(field), output) self.assertIn('something<div onclick="alert('oops')">.jpg', output) self.assertIn('my<div>file', output) self.assertNotIn('my<div>file', output)
def test_value_omitted_from_data(self): widget = ClearableFileInput() self.assertIs(widget.value_omitted_from_data({}, {}, 'field'), True) self.assertIs(widget.value_omitted_from_data({}, {'field': 'x'}, 'field'), False) self.assertIs(widget.value_omitted_from_data({'field-clear': 'y'}, {}, 'field'), False)
def test_accept(self): widget = ClearableFileInput() assert 'accept' not in widget.render(name='file', value='test.jpg') assert ["starts-with", "$Content-Type", ""] in widget.get_conditions(None) widget = ClearableFileInput(attrs={'accept': 'image/*'}) assert 'accept="image/*"' in widget.render(name='file', value='test.jpg') assert ["starts-with", "$Content-Type", "image/"] in widget.get_conditions('image/*') widget = ClearableFileInput(attrs={'accept': 'image/jpeg'}) assert 'accept="image/jpeg"' in widget.render(name='file', value='test.jpg') assert {"Content-Type": 'image/jpeg'} in widget.get_conditions('image/jpeg') widget = ClearableFileInput(attrs={'accept': 'application/pdf,image/*'}) assert 'accept="application/pdf,image/*"' in widget.render(name='file', value='test.jpg') assert ["starts-with", "$Content-Type", ""] in widget.get_conditions( 'application/pdf,image/*') assert {"Content-Type": 'application/pdf'} not in widget.get_conditions( 'application/pdf,image/*')
def render(self, name, value, attrs=None): output = ClearableFileInput.render(self, name, value, attrs) output += self.output_extra_data(value) return mark_safe(output)