Ticket #3297: 4722-newforms-file-imagefield.2.diff
File 4722-newforms-file-imagefield.2.diff, 10.3 KB (added by , 18 years ago) |
---|
-
django/db/models/fields/__init__.py
662 662 else: 663 663 func(new_data[upload_field_name]["filename"], new_data[upload_field_name]["content"], save) 664 664 665 def formfield_save_file(self, field_name, new_data, new_object, save=True): 666 if new_data[field_name]: 667 func = getattr(new_object, 'save_%s_file' % self.name) 668 func(new_data[field_name]["filename"], new_data[field_name]["content"], save) 669 665 670 def get_directory_name(self): 666 671 return os.path.normpath(datetime.datetime.now().strftime(self.upload_to)) 667 672 … … 670 675 f = os.path.join(self.get_directory_name(), get_valid_filename(os.path.basename(filename))) 671 676 return os.path.normpath(f) 672 677 678 def formfield(self, **kwargs): 679 defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'widget': forms.FileInput} 680 defaults.update(kwargs) 681 return forms.FileField(**defaults) 682 673 683 class FilePathField(Field): 674 684 def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs): 675 685 self.path, self.match, self.recursive = path, match, recursive … … 716 726 setattr(new_object, self.height_field, getattr(original_object, self.height_field)) 717 727 new_object.save() 718 728 729 def formfield(self, **kwargs): 730 defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'widget': forms.FileInput} 731 defaults.update(kwargs) 732 return forms.ImageField(**defaults) 733 719 734 class IntegerField(Field): 720 735 empty_strings_allowed = False 721 736 def get_manipulator_field_objs(self): -
django/newforms/models.py
18 18 19 19 This method is created for any form_for_model Form. 20 20 """ 21 from django.db import models 21 22 if self.errors: 22 23 raise ValueError("The %s could not be created because the data didn't validate." % self._model._meta.object_name) 23 24 return save_instance(self, self._model(), commit) … … 36 37 raise ValueError("The %s could not be changed because the data didn't validate." % opts.object_name) 37 38 clean_data = form.clean_data 38 39 for f in opts.fields: 39 if not f.editable or isinstance(f, models.AutoField): 40 continue 41 setattr(instance, f.name, clean_data[f.name]) 40 if clean_data.has_key(f.name): 41 if not f.editable or isinstance(f, models.AutoField): 42 continue 43 if isinstance(f, models.FileField): 44 continue 45 setattr(instance, f.name, clean_data[f.name]) 46 47 # FileField may need more info to save to specific paths 48 for f in opts.fields: 49 if isinstance(f, models.FileField) and clean_data.has_key(f.name): 50 f.formfield_save_file(f.name, clean_data, instance, save=False) 51 42 52 if commit: 43 53 instance.save() 44 54 for f in opts.many_to_many: … … 87 97 takes a database Field instance, plus **kwargs, and returns a form Field 88 98 instance with the given kwargs (i.e. 'initial'). 89 99 """ 100 from django.db import models 90 101 model = instance.__class__ 91 102 opts = model._meta 92 103 field_list = [] … … 96 107 current_value = f.value_from_object(instance) 97 108 formfield = formfield_callback(f, initial=current_value) 98 109 if formfield: 110 # FileFields are only required once, because we cannot print the 111 # existing data into the <form> 112 if isinstance(f, models.FileField) and current_value: 113 formfield.required = False 99 114 field_list.append((f.name, formfield)) 100 115 fields = SortedDictFromList(field_list) 101 116 return type(opts.object_name + 'InstanceForm', (form,), -
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 def clean(self, value): 112 super(FileField, self).clean(value) 113 if value in EMPTY_VALUES: 114 return None 115 else: 116 try: 117 content = value['content'] 118 except TypeError: 119 raise ValidationError(gettext("No file was submitted. Check the encoding type on the form.")) 120 if not content: 121 raise ValidationError(gettext(u'The submitted file is empty.')) 122 return value 123 124 class ImageField(FileField): 125 def clean(self, value): 126 super(ImageField, self).clean(value) 127 if value in EMPTY_VALUES: 128 return None 129 else: 130 from PIL import Image 131 from cStringIO import StringIO 132 try: 133 Image.open(StringIO(value['content'])) 134 except IOError: # Python Imaging Library doesn't recognize it as an image 135 raise ValidationError, gettext(u'Upload a valid image. The file you uploaded was either not an image or a corrupted image.') 136 return value 137 110 138 class IntegerField(Field): 111 139 def __init__(self, max_value=None, min_value=None, *args, **kwargs): 112 140 self.max_value, self.min_value = max_value, min_value -
tests/modeltests/model_forms/models.py
61 61 def __str__(self): 62 62 return self.phone 63 63 64 class NotRequiredFile(models.Model): 65 description = models.CharField(maxlength=50) 66 file = models.FileField(upload_to='files', blank=True) 67 68 def __str__(self): 69 return self.description 70 71 class RequiredFile(models.Model): 72 description = models.CharField(maxlength=50) 73 file = models.FileField(upload_to='files') 74 75 def __str__(self): 76 return self.description 77 64 78 __test__ = {'API_TESTS': """ 65 79 >>> from django.newforms import form_for_model, form_for_instance, save_instance, BaseForm, Form, CharField 66 80 >>> import datetime … … 377 391 378 392 >>> f = ModelChoiceField(Category.objects.filter(pk=1), required=False) 379 393 >>> print f.clean('') 394 395 Test for filefield 396 397 >>> form_data = {'description': 'FileField test', 'file': {'content': 'FileField test', 'filename': 'filetest.txt'} } 398 >>> no_file_form_data = {'description': 'FileField test'} 399 >>> bad_encoding_form_data = {'description': 'FileField test', 'file': 'wrong encoding'} 400 >>> TestRequiredFileForm = form_for_model(RequiredFile) 401 >>> empty_required_fileform = TestRequiredFileForm(auto_id=False) 402 >>> print empty_required_fileform.as_ul() 403 <li>Description: <input type="text" name="description" maxlength="50" /></li> 404 <li>File: <input type="file" name="file" /></li> 405 406 Test with data 407 >>> filled_required_fileform= TestRequiredFileForm(form_data, auto_id=False) 408 >>> filled_required_fileform.is_valid() 409 True 410 411 >>> required_file_instance = filled_required_fileform.save() 412 >>> print required_file_instance.file 413 files/filetest.txt 414 >>> TestInstanceRequiredFileForm = form_for_instance(required_file_instance) 415 >>> instance_required_fileform = TestInstanceRequiredFileForm(auto_id=False) 416 >>> instance_required_fileform.as_ul() 417 u'<li>Description: <input type="text" name="description" value="FileField test" maxlength="50" /></li>\\n<li>File: <input type="file" name="file" /></li>' 418 >>> required_file_instance.delete() 419 420 Bad data test 421 >>> filled_required_fileform=TestRequiredFileForm(no_file_form_data) 422 >>> filled_required_fileform.is_valid() 423 False 424 >>> print filled_required_fileform.errors 425 <ul class="errorlist"><li>file<ul class="errorlist"><li>This field is required.</li></ul></li></ul> 426 >>> TestNotRequiredFileForm = form_for_model(NotRequiredFile) 427 >>> filled_not_required_fileform=TestNotRequiredFileForm(no_file_form_data) 428 >>> filled_not_required_fileform.is_valid() 429 True 430 >>> filled_not_required_fileform=TestNotRequiredFileForm(bad_encoding_form_data) 431 >>> print filled_not_required_fileform.errors 432 <ul class="errorlist"><li>file<ul class="errorlist"><li>No file was submitted. Check the encoding type on the form.</li></ul></li></ul> 380 433 None 381 434 >>> f.clean('') 382 435 >>> f.clean('1') -
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" />' 178 170 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 171 # Textarea Widget ############################################################# 190 172 191 173 >>> w = Textarea()