Django

Code

Ticket #2534: filefield_core_fixes_6635.diff

File filefield_core_fixes_6635.diff, 6.6 kB (added by james.utter@gmail.com, 2 years ago)

updated patch to point to oldforms instead of forms

  • db/models/manipulators.py

    old new  
    170170                                pass 
    171171 
    172172                    for f in related.opts.fields: 
    173                         if f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) in (None, ''): 
     173                        if f.core and f.get_manipulator_new_data(rel_new_data, rel=True) in (None, ''): 
    174174                            all_cores_given = False 
    175                         elif f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) not in (None, ''): 
     175                        elif f.core and f.get_manipulator_new_data(rel_new_data, rel=True) not in (None, ''): 
    176176                            all_cores_blank = False 
    177177                        # If this field isn't editable, give it the same value it had 
    178178                        # previously, according to the given ID. If the ID wasn't 
  • db/models/fields/__init__.py

    old new  
    706706        return super(EmailField, self).formfield(**defaults) 
    707707 
    708708class FileField(Field): 
    709     def __init__(self, verbose_name=None, name=None, upload_to='', **kwargs): 
     709    def __init__(self, verbose_name=None, name=None, upload_to='', can_delete=False, **kwargs): 
    710710        self.upload_to = upload_to 
     711        self.can_delete = can_delete 
    711712        kwargs['max_length'] = kwargs.get('max_length', 100)         
    712713        Field.__init__(self, verbose_name, name, **kwargs) 
     714        assert (not self.can_delete) or self.null, "A FileField must have null=True if can_delete=True" 
    713715 
    714716    def get_db_prep_save(self, value): 
    715717        "Returns field's value prepared for saving into a database." 
     
    718720            return None 
    719721        return unicode(value) 
    720722 
     723    def get_manipulator_new_data(self, new_data, rel=False): 
     724        # Return the value which the field will take, if it is saved. 
     725        # This will be either the pathname of the uploaded file, or the 
     726        # pathname of the existing file, if no file was uploaded. 
     727        if rel: 
     728            extract = lambda field: (new_data.get("%s%s" % (self.name, field), [None])[0]) 
     729        else: 
     730            extract = lambda field: (new_data.get("%s%s" % (self.name, field), None)) 
     731        if extract('_delete'): 
     732            return None 
     733        try: 
     734            file = extract('_file') 
     735            return self.get_filename(file['filename']) 
     736        except (IndexError, KeyError, TypeError): 
     737            pass 
     738        return extract('') 
     739 
    721740    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True): 
    722741        field_list = Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel, follow) 
    723742        if not self.blank: 
     
    772791                os.remove(file_name) 
    773792 
    774793    def get_manipulator_field_objs(self): 
     794        if self.can_delete: 
     795            return [oldforms.FileUploadField, oldforms.HiddenField, oldforms.LabeledCheckbox] 
    775796        return [oldforms.FileUploadField, oldforms.HiddenField] 
    776797 
    777798    def get_manipulator_field_names(self, name_prefix): 
     799        if self.can_delete: 
     800            return [name_prefix + self.name + '_file', name_prefix + self.name, name_prefix + self.name + '_delete'] 
    778801        return [name_prefix + self.name + '_file', name_prefix + self.name] 
    779802 
    780803    def save_file(self, new_data, new_object, original_object, change, rel, save=True): 
    781         upload_field_name = self.get_manipulator_field_names('')[0] 
    782         if new_data.get(upload_field_name, False): 
     804        field_names = self.get_manipulator_field_names('') 
     805        upload_field_name = field_names[0] 
     806        # Delete only if delete checkbox is present and checked 
     807        if self.can_delete and ((rel and new_data.get(field_names[2], [False])[0]) or 
     808                                (not rel and new_data.get(field_names[2], False))): 
     809            file_name = getattr(original_object, 'get_%s_filename' % self.name)() 
     810            # If file exists, delete it 
     811            if file_name and os.path.exists(file_name): 
     812                os.remove(file_name) 
     813            setattr(new_object, self.name, None) 
     814            new_object.save() 
     815        elif new_data.get(upload_field_name, False): 
     816 
    783817            func = getattr(new_object, 'save_%s_file' % self.name) 
    784818            if rel: 
    785819                func(new_data[upload_field_name][0]["filename"], new_data[upload_field_name][0]["content"], save) 
     
    833867        FileField.__init__(self, verbose_name, name, **kwargs) 
    834868 
    835869    def get_manipulator_field_objs(self): 
     870        if self.can_delete: 
     871            return [oldforms.ImageUploadField, oldforms.HiddenField, oldforms.LabeledCheckbox] 
    836872        return [oldforms.ImageUploadField, oldforms.HiddenField] 
    837873 
    838874    def contribute_to_class(self, cls, name): 
  • oldforms/__init__.py

    old new  
    10481048            v(field_data, all_data) 
    10491049        except validators.ValidationError, e: 
    10501050            raise validators.CriticalValidationError, e.messages 
     1051 
     1052 
     1053class LabeledCheckbox(CheckboxField): 
     1054    """ 
     1055    A checkbox for which is_required is allowed to be set to False, and 
     1056    which optionally displays a text label before its form control. 
     1057    """ 
     1058    def __init__(self, field_name, checked_by_default=False, validator_list=None, is_required=False, label=None, max_length=None): 
     1059        self.label = label 
     1060        # This default is to support using this checkbox as a delete field in 
     1061        # FileField objects. It is only required because there is no easy way 
     1062        # to send unique constructor parameters to multiple manipulator field 
     1063        # objects. 
     1064        if self.label == None: 
     1065            self.label = ugettext("Delete") 
     1066        super(LabeledCheckbox, self).__init__(field_name, checked_by_default, validator_list) 
     1067 
     1068    def render(self, data): 
     1069        checked_html = '' 
     1070        if data or (data is '' and self.checked_by_default): 
     1071            checked_html = ' checked="checked"' 
     1072        label_html = '' 
     1073        if self.label: 
     1074            label_html = " %s " % self.label 
     1075        return '%s<input type="checkbox" id="%s" class="v%s" name="%s"%s value="on" />' % \ 
     1076            (label_html, self.get_id(), self.__class__.__name__, 
     1077            self.field_name, checked_html) 
     1078