Ticket #3297: 4549-with-more-tests-and-imagefield.patch
File 4549-with-more-tests-and-imagefield.patch, 11.4 KB (added by , 18 years ago) |
---|
-
django/db/models/fields/__init__.py
658 658 else: 659 659 func(new_data[upload_field_name]["filename"], new_data[upload_field_name]["content"]) 660 660 661 def formfield_save_file(self, field_name, new_data, new_object): 662 if new_data[field_name][0]: 663 func = getattr(new_object, 'save_%s_file' % self.name) 664 func(new_data[field_name][0]["filename"], new_data[field_name][0]["content"]) 665 661 666 def get_directory_name(self): 662 667 return os.path.normpath(datetime.datetime.now().strftime(self.upload_to)) 663 668 … … 666 671 f = os.path.join(self.get_directory_name(), get_valid_filename(os.path.basename(filename))) 667 672 return os.path.normpath(f) 668 673 674 def formfield(self, **kwargs): 675 defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'widget': forms.FileInput} 676 defaults.update(kwargs) 677 return forms.FileField(**defaults) 678 669 679 class FilePathField(Field): 670 680 def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs): 671 681 self.path, self.match, self.recursive = path, match, recursive … … 712 722 setattr(new_object, self.height_field, getattr(original_object, self.height_field)) 713 723 new_object.save() 714 724 725 def formfield(self, **kwargs): 726 defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'widget': forms.FileInput} 727 defaults.update(kwargs) 728 return forms.ImageField(**defaults) 729 715 730 class IntegerField(Field): 716 731 empty_strings_allowed = False 717 732 def get_manipulator_field_objs(self): -
django/newforms/models.py
16 16 17 17 This method is created for any form_for_model Form. 18 18 """ 19 from django.db import models 19 20 if self.errors: 20 21 raise ValueError("The %s could not be created because the data didn't validate." % self._model._meta.object_name) 21 22 return save_instance(self, self._model(), commit) … … 36 37 for f in opts.fields: 37 38 if not f.editable or isinstance(f, models.AutoField): 38 39 continue 40 if isinstance(f,models.FileField): 41 continue 39 42 setattr(instance, f.name, clean_data[f.name]) 40 43 if commit: 41 44 instance.save() 42 45 for f in opts.many_to_many: 43 46 setattr(instance, f.attname, clean_data[f.name]) 47 for f in opts.fields: 48 if isinstance(f, models.FileField): 49 f.formfield_save_file(f.name, clean_data, instance) 44 50 # GOTCHA: If many-to-many data is given and commit=False, the many-to-many 45 51 # data will be lost. This happens because a many-to-many options cannot be 46 52 # set on an object until after it's saved. Maybe we should raise an -
django/newforms/fields.py
10 10 import time 11 11 12 12 __all__ = ( 13 'Field', 'CharField', ' IntegerField',13 'Field', 'CharField', 'FileField', 'ImageField', 'IntegerField', 14 14 'DEFAULT_DATE_INPUT_FORMATS', 'DateField', 15 15 'DEFAULT_TIME_INPUT_FORMATS', 'TimeField', 16 16 'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField', … … 107 107 if self.max_length is not None and isinstance(widget, (TextInput, PasswordInput)): 108 108 return {'maxlength': str(self.max_length)} 109 109 110 class FileField(Field): 111 112 prev_error = False 113 114 def clean(self, value): 115 super(FileField, self).clean(value) 116 117 if value[0]: 118 try: 119 content = value[0]['content'] 120 except TypeError: 121 self.prev_error = True 122 raise ValidationError(gettext("No file was submitted. Check the encoding type on the form.")) 123 124 if not content: 125 self.prev_error = True 126 raise ValidationError(gettext(u'The submitted file is empty.')) 127 128 elif self.required: 129 if not value[1]: 130 self.prev_error = True 131 raise ValidationError(gettext(u'This field is required.')) 132 133 return value 134 135 class ImageField(FileField): 136 137 def clean(self, value): 138 super(ImageField, self).clean(value) 139 if value[0] and not self.prev_error: 140 from PIL import Image 141 from cStringIO import StringIO 142 try: 143 Image.open(StringIO(value[0]['content'])) 144 except IOError: # Python Imaging Library doesn't recognize it as an image 145 raise ValidationError, gettext(u'Upload a valid image. The file you uploaded was either not an image or a corrupted image.') 146 return value 147 110 148 class IntegerField(Field): 111 149 def __init__(self, max_value=None, min_value=None, *args, **kwargs): 112 150 self.max_value, self.min_value = max_value, min_value -
django/newforms/widgets.py
115 115 116 116 class FileInput(Input): 117 117 input_type = 'file' 118 119 def render(self,name,value,attrs=None,choices=()): 120 if value is None: value = '' 121 file_attrs = self.build_attrs(attrs, type='file', name=name+'_file') 122 final_attrs = self.build_attrs(attrs, type='hidden', name=name) 123 if value != '': final_attrs['value'] = smart_unicode(value) # only add the value attribute if a value is non-empty 124 125 if value != '': 126 currently = u'Currently: %s<br/>Change: ' % smart_unicode(value) 127 current = u' <input%s />' % flatatt(final_attrs) 128 else: 129 currently = u'' 130 current = u'' 131 132 return u'%s<input%s />%s' % (currently,flatatt(file_attrs),current) 133 134 def value_from_datadict(self,data,name): 135 return [data.get(name+'_file',None),data.get(name,None)] 118 136 119 137 class Textarea(Widget): 120 138 def render(self, name, value, attrs=None): -
tests/modeltests/model_forms/models.py
54 54 def __str__(self): 55 55 return self.headline 56 56 57 class NotRequiredFile(models.Model): 58 description = models.CharField(maxlength=50) 59 file = models.FileField(upload_to='files', blank=True) 60 61 def __str__(self): 62 return self.description 63 64 class RequiredFile(models.Model): 65 description = models.CharField(maxlength=50) 66 file = models.FileField(upload_to='files') 67 68 def __str__(self): 69 return self.description 70 57 71 __test__ = {'API_TESTS': """ 58 72 >>> from django.newforms import form_for_model, form_for_instance, save_instance, BaseForm, Form, CharField 59 73 >>> import datetime … … 370 384 Traceback (most recent call last): 371 385 ... 372 386 ValidationError: [u'Select a valid choice. 5 is not one of the available choices.'] 387 388 Test for filefield 389 390 >>> form_data = {'description': 'FileField test', 'file_file': {'content': 'FileField test', 'filename': 'filetest.txt'} } 391 >>> no_file_form_data = {'description': 'FileField test'} 392 >>> just_path_form_data = {'description': 'FileField test', 'file': 'files/filetest.txt'} 393 >>> bad_encoding_form_data = {'description': 'FileField test', 'file': 'files/filetest.txt', 'file_file': 'wrong encoding'} 394 >>> TestRequiredFileForm = form_for_model(RequiredFile) 395 >>> empty_required_fileform = TestRequiredFileForm(auto_id=False) 396 >>> print empty_required_fileform.as_ul() 397 <li>Description: <input type="text" name="description" maxlength="50" /></li> 398 <li>File: <input type="file" name="file_file" /></li> 399 400 Test with data 401 >>> filled_required_fileform= TestRequiredFileForm(form_data, auto_id=False) 402 >>> filled_required_fileform.is_valid() 403 True 404 405 >>> required_file_instance = filled_required_fileform.save() 406 >>> print required_file_instance.file 407 files/filetest.txt 408 >>> TestInstanceRequiredFileForm = form_for_instance(required_file_instance) 409 >>> instance_required_fileform = TestInstanceRequiredFileForm(auto_id=False) 410 >>> instance_required_fileform.as_ul() 411 u'<li>Description: <input type="text" name="description" value="FileField test" maxlength="50" /></li>\\n<li>File: Currently: files/filetest.txt<br/>Change: <input type="file" name="file_file" /> <input type="hidden" name="file" value="files/filetest.txt" /></li>' 412 >>> required_file_instance.delete() 413 414 Bad data test 415 >>> filled_required_fileform=TestRequiredFileForm(no_file_form_data) 416 >>> filled_required_fileform.is_valid() 417 False 418 >>> print filled_required_fileform.errors 419 <ul class="errorlist"><li>file<ul class="errorlist"><li>This field is required.</li></ul></li></ul> 420 >>> TestNotRequiredFileForm = form_for_model(NotRequiredFile) 421 >>> filled_not_required_fileform=TestNotRequiredFileForm(no_file_form_data) 422 >>> filled_not_required_fileform.is_valid() 423 True 424 >>> filled_not_required_fileform=TestNotRequiredFileForm(bad_encoding_form_data) 425 >>> print filled_not_required_fileform.errors 426 <ul class="errorlist"><li>file<ul class="errorlist"><li>No file was submitted. Check the encoding type on the form.</li></ul></li></ul> 427 >>> filled_not_required_fileform=TestNotRequiredFileForm(just_path_form_data) 428 >>> filled_not_required_fileform.is_valid() 429 True 430 >>> filled_required_fileform=TestRequiredFileForm(just_path_form_data) 431 >>> filled_required_fileform.is_valid() 432 True 373 433 """} -
tests/regressiontests/forms/tests.py
165 165 # FileInput Widget ############################################################ 166 166 167 167 >>> w = FileInput() 168 >>> w.render('email', '') 169 u'<input type="file" name="email" />' 170 >>> w.render('email', None) 171 u'<input type="file" name="email" />' 172 >>> w.render('email', 'test@example.com') 173 u'<input type="file" name="email" value="test@example.com" />' 174 >>> w.render('email', 'some "quoted" & ampersanded value') 175 u'<input type="file" name="email" value="some "quoted" & ampersanded value" />' 176 >>> w.render('email', 'test@example.com', attrs={'class': 'fun'}) 177 u'<input type="file" name="email" value="test@example.com" class="fun" />' 168 >>> w.render('file', '') 169 u'<input type="file" name="file_file" />' 170 >>> w.render('file', 'file/filetest.txt') 171 u'Currently: file/filetest.txt<br/>Change: <input type="file" name="file_file" /> <input type="hidden" name="file" value="file/filetest.txt" />' 178 172 179 You can also pass 'attrs' to the constructor:180 >>> w = FileInput(attrs={'class': 'fun'})181 >>> w.render('email', '')182 u'<input type="file" class="fun" name="email" />'183 >>> w.render('email', 'foo@example.com')184 u'<input type="file" class="fun" value="foo@example.com" name="email" />'185 186 >>> w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})187 u'<input type="file" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" name="email" />'188 189 173 # Textarea Widget ############################################################# 190 174 191 175 >>> w = Textarea()