Ticket #2534: filefield_core_fixes.diff
File filefield_core_fixes.diff, 6.6 KB (added by , 18 years ago) |
---|
-
django/db/models/manipulators.py
167 167 pass 168 168 169 169 for f in related.opts.fields: 170 if f.core and not isinstance(f, FileField) andf.get_manipulator_new_data(rel_new_data, rel=True) in (None, ''):170 if f.core and f.get_manipulator_new_data(rel_new_data, rel=True) in (None, ''): 171 171 all_cores_given = False 172 elif f.core and not isinstance(f, FileField) andf.get_manipulator_new_data(rel_new_data, rel=True) not in (None, ''):172 elif f.core and f.get_manipulator_new_data(rel_new_data, rel=True) not in (None, ''): 173 173 all_cores_blank = False 174 174 # If this field isn't editable, give it the same value it had 175 175 # previously, according to the given ID. If the ID wasn't -
django/db/models/fields/__init__.py
532 532 validators.isValidEmail(field_data, all_data) 533 533 534 534 class FileField(Field): 535 def __init__(self, verbose_name=None, name=None, upload_to='', **kwargs):535 def __init__(self, verbose_name=None, name=None, upload_to='', can_delete=False, **kwargs): 536 536 self.upload_to = upload_to 537 self.can_delete = can_delete 537 538 Field.__init__(self, verbose_name, name, **kwargs) 539 assert (not self.can_delete) or self.null, "A FileField must have null=True if can_delete=True" 538 540 539 541 def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True): 540 542 field_list = Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel, follow) … … 572 574 field_list[1].validator_list.append(isWithinMediaRoot) 573 575 return field_list 574 576 577 def get_manipulator_new_data(self, new_data, rel=False): 578 # Return the value which the field will take, if it is saved. 579 # This will be either the pathname of the uploaded file, or the 580 # pathname of the existing file, if no file was uploaded. 581 if rel: 582 extract = lambda field: (new_data.get("%s%s" % (self.name, field), [None])[0]) 583 else: 584 extract = lambda field: (new_data.get("%s%s" % (self.name, field), None)) 585 if extract('_delete'): 586 return None 587 try: 588 file = extract('_file') 589 return self.get_filename(file['filename']) 590 except (IndexError, KeyError, TypeError): 591 pass 592 return extract('') 593 575 594 def contribute_to_class(self, cls, name): 576 595 super(FileField, self).contribute_to_class(cls, name) 577 596 setattr(cls, 'get_%s_filename' % self.name, curry(cls._get_FIELD_filename, field=self)) … … 590 609 os.remove(file_name) 591 610 592 611 def get_manipulator_field_objs(self): 612 if self.can_delete: 613 return [forms.FileUploadField, forms.HiddenField, forms.LabeledCheckbox] 593 614 return [forms.FileUploadField, forms.HiddenField] 594 615 595 616 def get_manipulator_field_names(self, name_prefix): 617 if self.can_delete: 618 return [name_prefix + self.name + '_file', name_prefix + self.name, name_prefix + self.name + '_delete'] 596 619 return [name_prefix + self.name + '_file', name_prefix + self.name] 597 620 598 621 def save_file(self, new_data, new_object, original_object, change, rel): 599 upload_field_name = self.get_manipulator_field_names('')[0] 600 if new_data.get(upload_field_name, False): 622 field_names = self.get_manipulator_field_names('') 623 upload_field_name = field_names[0] 624 # Delete only if delete checkbox is present and checked 625 if self.can_delete and ((rel and new_data.get(field_names[2], [False])[0]) or 626 (not rel and new_data.get(field_names[2], False))): 627 file_name = getattr(original_object, 'get_%s_filename' % self.name)() 628 # If file exists, delete it 629 if file_name and os.path.exists(file_name): 630 os.remove(file_name) 631 setattr(new_object, self.name, None) 632 new_object.save() 633 elif new_data.get(upload_field_name, False): 601 634 func = getattr(new_object, 'save_%s_file' % self.name) 602 635 if rel: 603 636 func(new_data[upload_field_name][0]["filename"], new_data[upload_field_name][0]["content"]) … … 635 668 FileField.__init__(self, verbose_name, name, **kwargs) 636 669 637 670 def get_manipulator_field_objs(self): 671 if self.can_delete: 672 return [forms.ImageUploadField, forms.HiddenField, forms.LabeledCheckbox] 638 673 return [forms.ImageUploadField, forms.HiddenField] 639 674 640 675 def contribute_to_class(self, cls, name): -
django/forms/__init__.py
993 993 v(field_data, all_data) 994 994 except validators.ValidationError, e: 995 995 raise validators.CriticalValidationError, e.messages 996 997 class LabeledCheckbox(CheckboxField): 998 """ 999 A checkbox for which is_required is allowed to be set to False, and 1000 which optionally displays a text label before its form control. 1001 """ 1002 def __init__(self, field_name, checked_by_default=False, validator_list=None, is_required=False, label=None): 1003 self.label = label 1004 # This default is to support using this checkbox as a delete field in 1005 # FileField objects. It is only required because there is no easy way 1006 # to send unique constructor parameters to multiple manipulator field 1007 # objects. 1008 if self.label == None: 1009 self.label = gettext_lazy("Delete") 1010 super(LabeledCheckbox, self).__init__(field_name, checked_by_default, validator_list) 1011 1012 def render(self, data): 1013 checked_html = '' 1014 if data or (data is '' and self.checked_by_default): 1015 checked_html = ' checked="checked"' 1016 label_html = '' 1017 if self.label: 1018 label_html = " %s " % self.label 1019 return '%s<input type="checkbox" id="%s" class="v%s" name="%s"%s value="on" />' % \ 1020 (label_html, self.get_id(), self.__class__.__name__, 1021 self.field_name, checked_html) 1022