gitter
gitter

Reputation: 1726

File Upload gives Bad Request in Django using modelform

I am trying to upload a file using a model form but form.save() is giving me bad request. This is my model:

class cv(models.Model):
    name = models.CharField('Name', max_length=64, null=True)
    path_to_cv = models.FileField('CV', upload_to='/', null=True)

Here is the form:

class Step2(forms.ModelForm):
    class Meta:
    model = cv

Here is the view:

def phdStep2(request):
    if request.method == 'POST':
        form = PhdStep2(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/step/3/')
    else:
        form = PhdStep2()
    return render(request, 'step2.html', {'form': form})

Here is the template for form:

<form action="/step/2" method="post" class="well form" role="form" enctype="multipart/form-data">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
    <button type="submit" class="btn btn-primary">
        Submit
    </button>
{% endbuttons %}
</form>

Here is the media_root in settings.py:

MEDIA_ROOT = '/home/supertux/PyCharm/myproject/admissions/media'
MEDIA_URL = '/media/'

I have read like 10s of such threads and find that most times problem was enctype in form which i already incorporated. Now as i understand, this should upload the file since its a model form, but i always get a 400 Bad Request. I want to store the name and path to the file in database. What am i doing wrong?

Upvotes: 4

Views: 4779

Answers (3)

Jace Ho
Jace Ho

Reputation: 31

Try to catch an Exception if you don't know what's going on.

The point is:

django FileField try to explain file path with .* to an relative path but /* to an absolute path

It would be SuspiciousFileOperation exception located in django.core.files.storage module which seems a magic here,

def path(self, name):
try:
    path = safe_join(self.location, name)
except ValueError:
    raise SuspiciousFileOperation("Attempted access to '%s' denied." % name)
return os.path.normpath(path)

Upvotes: 1

Feler404
Feler404

Reputation: 1

When upload_to="" doesn't work, try upload_to=".". Path "." is default path MEDIA_ROOT (in Django 1.6.x)

Upvotes: -2

Scott Woodall
Scott Woodall

Reputation: 10676

Try replacing upload_to='/' with upload_to='%Y/%m/%d' and make sure that the user running your django application has write permissions to MEDIA_ROOT. If neither of these suggestions help you can turn on some additional logging to hopefully reveal what the issue is.

Update: I'd recommended that you set upload_to to something so you don't have 100's if not 1000's of files pile up in the same directory. It will be come hard to manage over time. I haven't tried this but what if you set it to upload_to='', will it accept that? In Django 1.6 they made this parameter optional.

Update2: I was incorrect about what version this was made optional. I was reading the development version of the docs. Apologies.

Upvotes: 3

Related Questions