[HELP]Django request.FILES always empty on file upload

55 views
Skip to first unread message

Alexandre Briskieviez Silva

unread,
Jun 25, 2014, 5:37:18 PM6/25/14
to cam...@googlegroups.com
[HELP]Django request.FILES always empty on file upload

Hi all,

I'm struggling with this problem for days. When trying to upload a file using a FileField, the form doesn't post the file data to the server. It works perfectly if you use a text field, but for some reason it doesn't recognize the file, as it doesn't show up on request.FILES, or request.POSTS.

MEDIA_ROOT and MEDIA_URL configuration:

MEDIA_ROOT = '/home/grove/pootleImages/'
MEDIA_URL = '/pootleImages/'
get_unit_context decorator in decorators.py:

def get_unit_context(permission_codes):

def wrap_f(f):

    @wraps(f)
    def decorated_f(request, uid, *args, **kwargs):
        unit = get_object_or_404(
                Unit.objects.select_related("store__translation_project",
                                            "store__parent"),
                id=uid,
        )
        _common_context(request, unit.store.translation_project,
                        permission_codes)
        request.unit = unit
        request.store = unit.store
        request.directory = unit.store.parent

        return f(request, unit, *args, **kwargs)

    return decorated_f

return wrap_f
My forms.py method:

def unit_image_form_factory(language):

    image_attrs = {
        'lang': language.code,
        'dir': language.direction,
        'class': 'images expanding focusthis',
        'rows': 2,
        'tabindex': 15,
    }


    class UnitImageForm(forms.ModelForm):

        class Meta:
            fields = ('image',)
            model = Unit

        # It works if using a CharField!
        #image = forms.CharField(required=True,
          #                                   label=_("Image"),
           #                                  widget=forms.Textarea(
            #                                 attrs=image_attrs))
        image= forms.FileField(required=True, label=_('Image'),
                                             widget=forms.FileInput(
                                             attrs=image_attrs))
        def __init__(self, *args, **kwargs):
            self.request = kwargs.pop('request', None)
            super(UnitImageForm, self).__init__(*args, **kwargs)


        def save(self):
            super(UnitImageForm, self).save()


    return UnitImageForm
My models.py snippet:

class Unit(models.Model, base.TranslationUnit):
    # ...
    # ...
    # It works if using a TextField!
    #image = models.TextField(null=True, blank=True)
    image = models.FileField(upload_to=".", blank=True, null=True)
    # ...
    # ...
My urls.py snippet:

url(r'^xhr/units/(?P<uid>[0-9]+)/image/?$',
    'image',
    name='pootle-xhr-units-image'),
My views.py method:

@require_POST
@ajax_required
@get_unit_context('translate')
def image(request, unit):
    """Stores a new image for the given ``unit``.

    :return: If the form validates, the cleaned image is returned.
             An error message is returned otherwise.
    """
    # Update current unit instance's attributes
    unit.uploaded_by = request.profile
    unit.uploaded_on = timezone.now()

    language = request.translation_project.language
    form = unit_image_form_factory(language)(request.POST, request.FILES, instance=unit,
                                               request=request)

    if form.is_valid():
        form.save()
        context = {
            'unit': unit,
            'language': language,
        }
        t = loader.get_template('unit/image.html')
        c = RequestContext(request, context)

        json = {'image': t.render(c)}
        rcode = 200
    else:
        json = {'msg': _("Image submission failed.")}
        rcode = 400

    response = simplejson.dumps(json)

    return HttpResponse(response, status=rcode, mimetype="application/json")
My HTML template for the image upload:

<div id="upload-image">
    <form enctype="multipart/form-data" method="post" action="{% url 'pootle-xhr-units-image' unit.id %}" id="image-form">
    <input type="file" name="image" id="id_image" />
    <p><input type="submit" value="{% trans 'Upload' %}" /></p>
    </form>
</div>
When the form is instantiated, request.POST does not return the file browsed by the user, neither request.FILES. form.errors just returns "This field is required" The form object returns the following:

<tr><th><label for="id_image">Image:</label></th><td><ul class="errorlist"><li>This field is required.</li>
</ul><input lang="pl" rows="2" name="image" id="id_image" type="file" class="images expanding focusthis" dir="ltr" tabindex="15" /></td></tr>
And when the user clicks the submit button, the following POST error occurs:

"POST /xhr/units/74923/image HTTP/1.1" 400 35
I could bypass it by including required=False to the image property, but the file is not posted anyway.

Thank you,

Alex

Daniel O'Donovan

unread,
Jun 27, 2014, 3:56:27 AM6/27/14
to cam...@googlegroups.com
On 25/06/2014 22:37, Alexandre Briskieviez Silva wrote:
> [HELP]Django request.FILES always empty on file upload
>
> Hi all,
>
> I'm struggling with this problem for days. When trying to upload a file
> using a FileField, the form doesn't post the file data to the server. It
> works perfectly if you use a text field, but for some reason it doesn't
> recognize the file, as it doesn't show up on request.FILES, or
> request.POSTS.

Hmm, there's too much code here. Have you tried breaking down the
problem into smaller bitesize pieces (without all the decorators and
faff) and checking they work? If they do, slowly add in the missing
pieces until you find the one that breaks ...

Other than those (slightly patronising, sorry) words of advice, have you
tried cleaning the form? Instead of

>>> request.FILES

take a look at

>>> request.cleaned_data['image']

Another obvious gotcha, multipart files are only available in HTML5 -
you are using HTML5 and a compatible browser right :)

Finally, Hello to Michigan! (abri...@ltu.edu) are you visiting Cambridge?

Dan
> --
> You received this message because you are subscribed to the Google
> Groups "Cambridge and East Anglian Python Users Group" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to campug+un...@googlegroups.com
> <mailto:campug+un...@googlegroups.com>.
> To post to this group, send email to cam...@googlegroups.com
> <mailto:cam...@googlegroups.com>.
> Visit this group at http://groups.google.com/group/campug.
> For more options, visit https://groups.google.com/d/optout.


--
Dan (TM)

Steve McConville

unread,
Jun 27, 2014, 4:22:17 AM6/27/14
to cam...@googlegroups.com
Hi Alexandre,

The 400 makes me wonder if you have a permissions issue with the MEDIA_ROOT directory. If it works with MEDIA_ROOT="/tmp/" then this is likely the problem.

The django-users mailing list (https://groups.google.com/forum/#!forum/django-users) would definitely have plenty of people who can help; it's the first place I would go for help with this kind of thing.


--
You received this message because you are subscribed to the Google Groups "Cambridge and East Anglian Python Users Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to campug+un...@googlegroups.com.
To post to this group, send email to cam...@googlegroups.com.

Visit this group at http://groups.google.com/group/campug.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages