Resubmitting Image in ImageField after Validation

2019-02-10 19:53发布

问题:

I have, in my admin interface, a form with a ImageField. Everything works great except when some other field raises a validation error. In those cases, the form returns to the user for correction, but the already loaded image file is cleared from the form.

Any idea in how to, somehow, reload the already submitted image to the form in order to allow the image beeing saved?

Thanks!

SOme interesting bits of code:

class DealForm(forms.ModelForm):
    image = forms.ImageField(required=False,widget=AdminImageWidget)

    def clean():
        data = self.cleaned_data
        date_start = data.get('date_start')
        date_end = data.get('date_end')
        (... several other validations ...)
        return data

.

class AdminImageWidget(forms.FileInput):
    def __init__(self, attrs={}):
        super(AdminImageWidget, self).__init__(attrs)

    def render(self, name, value, attrs=None):
        output = []
        if value and hasattr(value, "url"):
            output.append(('<a target="_blank" href="%s">' 
                            '<img src="%s" /></a> '
                            % (value.url, value.url_200x150)))
        output.append(super(AdminImageWidget, self).render(name, value, attrs))
        return mark_safe(u''.join(output))

回答1:

HTML <input type="file"> fields cannot be prepopulated with data. Therefore, if validation fails on another field, you will have to re-select the image.

It's a HTML / browser security measure. As in, no way around it!

Imagine if a site could inject C:\Windows\something_important into a form in the corner of the page?


If this is critical functionality, you could...

  1. Force the file to be uploaded before form validation and stash the file name in the user session
  2. Set up your template to display a "success" message on re-display if file is uploaded
  3. Disable file field validation when session contains upload info
  4. Pull the filename from your session upon true valid form submission


回答2:

Here is django app, called django-file-resubmit. It solves exactly this problem.

https://github.com/un1t/django-file-resubmit