Ticket #2534: filefield_core_fixes_6635.diff

File filefield_core_fixes_6635.diff, 6.6 KB (added by james.utter@…, 8 years ago)

updated patch to point to oldforms instead of forms

  • db/models/manipulators.py

     
    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

     
    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

     
    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
Back to Top