Ticket #3297: 5268-newforms-file-imagefield.diff
File 5268-newforms-file-imagefield.diff, 8.6 KB (added by , 17 years ago) |
---|
-
django/db/models/fields/__init__.py
665 665 else: 666 666 func(new_data[upload_field_name]["filename"], new_data[upload_field_name]["content"], save) 667 667 668 def formfield_save_file(self, field_name, new_data, new_object, save=True): 669 if new_data[field_name]: 670 func = getattr(new_object, 'save_%s_file' % self.name) 671 func(new_data[field_name]["filename"], new_data[field_name]["content"], save) 672 668 673 def get_directory_name(self): 669 674 return os.path.normpath(datetime.datetime.now().strftime(self.upload_to)) 670 675 … … 673 678 f = os.path.join(self.get_directory_name(), get_valid_filename(os.path.basename(filename))) 674 679 return os.path.normpath(f) 675 680 681 def formfield(self, **kwargs): 682 defaults = {'form_class': forms.FileField} 683 defaults.update(kwargs) 684 return super(FileField, self).formfield(**defaults) 685 676 686 class FilePathField(Field): 677 687 def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs): 678 688 self.path, self.match, self.recursive = path, match, recursive … … 719 729 setattr(new_object, self.height_field, getattr(original_object, self.height_field)) 720 730 new_object.save() 721 731 732 def formfield(self, **kwargs): 733 defaults = {'form_class': forms.ImageField} 734 defaults.update(kwargs) 735 return super(ImageField, self).formfield(**defaults) 736 722 737 class IntegerField(Field): 723 738 empty_strings_allowed = False 724 739 def get_manipulator_field_objs(self): -
django/newforms/models.py
31 31 for f in opts.fields: 32 32 if not f.editable or isinstance(f, models.AutoField) or not f.name in cleaned_data: 33 33 continue 34 if isinstance(f, models.FileField): 35 continue 34 36 if fields and f.name not in fields: 35 37 continue 36 38 setattr(instance, f.name, cleaned_data[f.name]) 39 40 # FileField may need more info to save to specific paths 41 for f in opts.fields: 42 if isinstance(f, models.FileField) and cleaned_data.has_key(f.name): 43 f.formfield_save_file(f.name, cleaned_data, instance, save=False) 44 37 45 if commit: 38 46 instance.save() 39 47 for f in opts.many_to_many: … … 94 102 takes a database Field instance, plus **kwargs, and returns a form Field 95 103 instance with the given kwargs (i.e. 'initial'). 96 104 """ 105 from django.db import models 97 106 model = instance.__class__ 98 107 opts = model._meta 99 108 field_list = [] … … 105 114 current_value = f.value_from_object(instance) 106 115 formfield = formfield_callback(f, initial=current_value) 107 116 if formfield: 117 # FileFields are only required once, because we cannot print the 118 # existing data into the <form> 119 if isinstance(f, models.FileField) and current_value: 120 formfield.required = False 108 121 field_list.append((f.name, formfield)) 109 122 base_fields = SortedDictFromList(field_list) 110 123 return type(opts.object_name + 'InstanceForm', (form,), -
django/newforms/fields.py
10 10 from django.utils.encoding import smart_unicode 11 11 12 12 from util import ErrorList, ValidationError 13 from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple 13 from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, FileInput 14 14 15 15 __all__ = ( 16 'Field', 'CharField', ' IntegerField',16 'Field', 'CharField', 'FileField', 'ImageField', 'IntegerField', 17 17 'DEFAULT_DATE_INPUT_FORMATS', 'DateField', 18 18 'DEFAULT_TIME_INPUT_FORMATS', 'TimeField', 19 19 'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField', … … 111 111 if self.max_length is not None and isinstance(widget, (TextInput, PasswordInput)): 112 112 return {'maxlength': str(self.max_length)} 113 113 114 class FileField(Field): 115 widget = FileInput 116 117 def clean(self, value): 118 super(FileField, self).clean(value) 119 if value in EMPTY_VALUES: 120 return None 121 else: 122 try: 123 content = value['content'] 124 except TypeError: 125 raise ValidationError(gettext("No file was submitted. Check the encoding type on the form.")) 126 if not content: 127 raise ValidationError(gettext(u'The submitted file is empty.')) 128 return value 129 130 class ImageField(FileField): 131 def clean(self, value): 132 super(ImageField, self).clean(value) 133 if value in EMPTY_VALUES: 134 return None 135 else: 136 from PIL import Image 137 from cStringIO import StringIO 138 try: 139 Image.open(StringIO(value['content'])) 140 except IOError: # Python Imaging Library doesn't recognize it as an image 141 raise ValidationError, gettext(u'Upload a valid image. The file you uploaded was either not an image or a corrupted image.') 142 return value 143 114 144 class IntegerField(Field): 115 145 def __init__(self, max_value=None, min_value=None, *args, **kwargs): 116 146 self.max_value, self.min_value = max_value, min_value -
tests/modeltests/model_forms/models.py
68 68 def __str__(self): 69 69 return self.phone 70 70 71 class NotRequiredFile(models.Model): 72 description = models.CharField(maxlength=50) 73 file = models.FileField(upload_to='files', blank=True) 74 75 def __str__(self): 76 return self.description 77 78 class RequiredFile(models.Model): 79 description = models.CharField(maxlength=50) 80 file = models.FileField(upload_to='files') 81 82 def __str__(self): 83 return self.description 84 71 85 __test__ = {'API_TESTS': """ 72 86 >>> from django.newforms import form_for_model, form_for_instance, save_instance, BaseForm, Form, CharField 73 87 >>> import datetime … … 442 456 443 457 >>> f = ModelChoiceField(Category.objects.filter(pk=1), required=False) 444 458 >>> print f.clean('') 459 460 Test for filefield 461 462 >>> form_data = {'description': 'FileField test', 'file': {'content': 'FileField test', 'filename': 'filetest.txt'} } 463 >>> no_file_form_data = {'description': 'FileField test'} 464 >>> bad_encoding_form_data = {'description': 'FileField test', 'file': 'wrong encoding'} 465 >>> TestRequiredFileForm = form_for_model(RequiredFile) 466 >>> empty_required_fileform = TestRequiredFileForm(auto_id=False) 467 >>> print empty_required_fileform.as_ul() 468 <li>Description: <input type="text" name="description" maxlength="50" /></li> 469 <li>File: <input type="file" name="file" /></li> 470 471 Test with data 472 >>> filled_required_fileform= TestRequiredFileForm(form_data, auto_id=False) 473 >>> filled_required_fileform.is_valid() 474 True 475 476 >>> required_file_instance = filled_required_fileform.save() 477 >>> print required_file_instance.file 478 files/filetest.txt 479 >>> TestInstanceRequiredFileForm = form_for_instance(required_file_instance) 480 >>> instance_required_fileform = TestInstanceRequiredFileForm(auto_id=False) 481 >>> instance_required_fileform.as_ul() 482 u'<li>Description: <input type="text" name="description" value="FileField test" maxlength="50" /></li>\\n<li>File: <input type="file" name="file" /></li>' 483 >>> required_file_instance.delete() 484 485 Bad data test 486 >>> filled_required_fileform=TestRequiredFileForm(no_file_form_data) 487 >>> filled_required_fileform.is_valid() 488 False 489 >>> print filled_required_fileform.errors 490 <ul class="errorlist"><li>file<ul class="errorlist"><li>This field is required.</li></ul></li></ul> 491 >>> TestNotRequiredFileForm = form_for_model(NotRequiredFile) 492 >>> filled_not_required_fileform=TestNotRequiredFileForm(no_file_form_data) 493 >>> filled_not_required_fileform.is_valid() 494 True 495 >>> filled_not_required_fileform=TestNotRequiredFileForm(bad_encoding_form_data) 496 >>> print filled_not_required_fileform.errors 497 <ul class="errorlist"><li>file<ul class="errorlist"><li>No file was submitted. Check the encoding type on the form.</li></ul></li></ul> 445 498 None 446 499 >>> f.clean('') 447 500 >>> f.clean('1')