Ticket #3297: 5722-newforms-file-imagefield.diff
File 5722-newforms-file-imagefield.diff, 8.8 KB (added by , 17 years ago) |
---|
-
django/db/models/fields/__init__.py
734 734 else: 735 735 func(new_data[upload_field_name]["filename"], new_data[upload_field_name]["content"], save) 736 736 737 def formfield_save_file(self, field_name, new_data, new_object, save=True): 738 if new_data[field_name]: 739 func = getattr(new_object, 'save_%s_file' % self.name) 740 func(new_data[field_name]["filename"], new_data[field_name]["content"], save) 741 737 742 def get_directory_name(self): 738 743 return os.path.normpath(force_unicode(datetime.datetime.now().strftime(smart_str(self.upload_to)))) 739 744 … … 742 747 f = os.path.join(self.get_directory_name(), get_valid_filename(os.path.basename(filename))) 743 748 return os.path.normpath(f) 744 749 750 def formfield(self, **kwargs): 751 defaults = {'form_class': forms.FileField} 752 defaults.update(kwargs) 753 return super(FileField, self).formfield(**defaults) 754 745 755 class FilePathField(Field): 746 756 def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs): 747 757 self.path, self.match, self.recursive = path, match, recursive … … 790 800 setattr(new_object, self.height_field, getattr(original_object, self.height_field)) 791 801 new_object.save() 792 802 803 def formfield(self, **kwargs): 804 defaults = {'form_class': forms.ImageField} 805 defaults.update(kwargs) 806 return super(ImageField, self).formfield(**defaults) 807 793 808 class IntegerField(Field): 794 809 empty_strings_allowed = False 795 810 def get_manipulator_field_objs(self): -
django/newforms/models.py
32 32 for f in opts.fields: 33 33 if not f.editable or isinstance(f, models.AutoField) or not f.name in cleaned_data: 34 34 continue 35 if isinstance(f, models.FileField): 36 continue 35 37 if fields and f.name not in fields: 36 38 continue 37 39 setattr(instance, f.name, cleaned_data[f.name]) 40 41 # FileField may need more info to save to specific paths 42 for f in opts.fields: 43 if isinstance(f, models.FileField) and cleaned_data.has_key(f.name): 44 f.formfield_save_file(f.name, cleaned_data, instance, save=False) 45 38 46 if commit: 39 47 instance.save() 40 48 for f in opts.many_to_many: … … 95 103 takes a database Field instance, plus **kwargs, and returns a form Field 96 104 instance with the given kwargs (i.e. 'initial'). 97 105 """ 106 from django.db import models 98 107 model = instance.__class__ 99 108 opts = model._meta 100 109 field_list = [] … … 106 115 current_value = f.value_from_object(instance) 107 116 formfield = formfield_callback(f, initial=current_value) 108 117 if formfield: 118 # FileFields are only required once, because we cannot print the 119 # existing data into the <form> 120 if isinstance(f, models.FileField) and current_value: 121 formfield.required = False 109 122 field_list.append((f.name, formfield)) 110 123 base_fields = SortedDictFromList(field_list) 111 124 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 try: 16 16 from decimal import Decimal, DecimalException … … 18 18 from django.utils._decimal import Decimal, DecimalException 19 19 20 20 __all__ = ( 21 'Field', 'CharField', ' IntegerField',21 'Field', 'CharField', 'FileField', 'ImageField', 'IntegerField', 22 22 'DEFAULT_DATE_INPUT_FORMATS', 'DateField', 23 23 'DEFAULT_TIME_INPUT_FORMATS', 'TimeField', 24 24 'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField', … … 122 122 if self.max_length is not None and isinstance(widget, (TextInput, PasswordInput)): 123 123 return {'maxlength': str(self.max_length)} 124 124 125 class FileField(Field): 126 widget = FileInput 127 128 def clean(self, value): 129 super(FileField, self).clean(value) 130 if value in EMPTY_VALUES: 131 return None 132 else: 133 try: 134 content = value['content'] 135 except TypeError: 136 raise ValidationError(gettext("No file was submitted. Check the encoding type on the form.")) 137 if not content: 138 raise ValidationError(gettext(u'The submitted file is empty.')) 139 return value 140 141 class ImageField(FileField): 142 def clean(self, value): 143 super(ImageField, self).clean(value) 144 if value in EMPTY_VALUES: 145 return None 146 else: 147 from PIL import Image 148 from cStringIO import StringIO 149 try: 150 Image.open(StringIO(value['content'])) 151 except IOError: # Python Imaging Library doesn't recognize it as an image 152 raise ValidationError, gettext(u'Upload a valid image. The file you uploaded was either not an image or a corrupted image.') 153 return value 154 125 155 class IntegerField(Field): 126 156 def __init__(self, max_value=None, min_value=None, *args, **kwargs): 127 157 self.max_value, self.min_value = max_value, min_value -
tests/modeltests/model_forms/models.py
68 68 def __unicode__(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')