-2

Ok, I know there is many question same to mine, but I didn't find any answer to solve my problem.I am newbie to Django, so please keep in mind.

I need to do a from which will upload a file:

Here is my upload.py(which is a views.py)

from django.http import HttpResponse
def upload(request)
  viewfile = HttpResponse()
  viewfile.write('''
             <html>
             <body>
             <form action="/upload_done/" method="POST" enctype="multipart/form-data" {% csrf_token %}>
                 <label for="file">Filename:</label>
                 <input type="file" name="up_file" >
                  <br />
                  <input type="submit" name="submit" value="Submit" >
             </form>
    return HttpResponse(viewfile)

Now My upload_done.py:

from django.http import HttpResponseRedirect
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.http import HttpResponse
import tempfile
import shutil
def upload_done(request):
  viewfile = HttpResponse()
  #####First I Tried this
  Up_file = request.FILES['up_file']
   """ It gives multivalue error('' 'up_file' '')
  # then I change my upload.py input type file to text & try to collect information
  # and change here Up_file = request.FILES['up_file'] to this
   Up_file = request.POST['up_file']

Now I am getting 403 csrf error From Django doc, Iam not able to understand how templates(only able to understand file.html should be same name as views.py's funcution name) works.

Please assist me how to use post method & how to upload a file.Thanks In advance...

I have tried like this also(write in /home/user/myproject/template/upload_form.html)(Note: template dirctory works properly)

<html>
             <body>
             <form action="/upload_done/" method="POST" enctype="multipart/form-data" {% csrf_token %}>
                 <label for="file">Filename:</label>
                 <input type="file" name="up_file" >
                  <br />
                  <input type="submit" name="submit" value="Submit" >
             </form>

& In above 2nd Views.py(i.e. upload_form.py) replace 'Up_file = request.FILES['up_file']' to this

if request.method == 'POST':
    return render(request, 'upload_form.html',{})

But getting error (must return HttpResponse)

Zulu
  • 8,765
  • 9
  • 49
  • 56
Swagat
  • 617
  • 5
  • 16
  • No no, You're doing it wrong. [Go through the tutorial please](https://docs.djangoproject.com/en/1.6/intro/tutorial01/). Take the time to learn a little about django. It's obvious you don't know even the basics – yuvi Feb 07 '14 at 10:15
  • If the method isn't POST, you're not giving any response (which means no HttpResponse being returned, and the following error). Please listen to my advice and go over the tutorial. Deadline or not, you'll never make any progress if you don't know the basic fundamentals of the framework. You'll just keep coming here and copy-pasting code you don't understand – yuvi Feb 07 '14 at 10:45
  • Also, you're returning render in the post with no feedback. You're not doing anything with the form. I doubt that's what you're trying to do. And also, csrf needs to be after the form but not inside the `form` tag itself – yuvi Feb 07 '14 at 10:48
  • Yes I know What are you saying, but I need only post method for upload file, I got see csrf inside the form in this [answer](http://stackoverflow.com/questions/20895526/forbidden-403-csrf-verification-failed-request-aborted-even-using-the-csr). So Please Just tell me Steps(i.e. which will work after what include template, views) – Swagat Feb 07 '14 at 10:58
  • See my answer. Notice I'm doing the redirecting through Django (instead of using the `action` directive). You should always attempt to do as much as possible using django. With that in mind, it might be easier if you'd use a django form instead of writing all that html – yuvi Feb 07 '14 at 11:01

2 Answers2

2

You can't write HTML directly into your view and expect it to be treated as a template automatically. While you could pass that string into the template rendering system, there are very good reasons for keeping your templates and your views separate.

Please go back and look again at all the examples that show you how to render a template, and do that instead of hard-coding your HTML. The tutorial is extremely good and shows you exactly how to do this, so there's no point saying "I am not able to understand how templates work".

Also, you should not write separate Python files for each view. You can have multiple view functions in each file. And when you've finished learning about templates, then you can go and read the documentation about forms.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Thank you @Daniel , Felling lucky That U r answering me again.. The thing is this is a small project with few page. & the main problem is I am on deadline. So If Possible, Please guide me some basic about template & form post. – Swagat Feb 07 '14 at 10:22
  • 2
    Seriously, this is not difficult at all. Put that into a template file, and do `return render(request, 'upload_form.html', {})`. – Daniel Roseman Feb 07 '14 at 10:28
  • Just follow [the tutorial](https://docs.djangoproject.com/en/1.6/intro/tutorial04/#write-a-simple-form). – yuvi Feb 07 '14 at 10:31
2

This is how it's supposed to look like:

upload_form.html:

<form method="POST" enctype="multipart/form-data" >
{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" name="submit" value="Submit" >
</form>

view (based on the example from the docs):

from django import forms
class UploadFileForm(forms.Form):
    up_file = forms.FileField()

def handle_uploaded_file(f):
    with open('some/file/name.xls', 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)

from django.http import HttpResponseRedirect
from django.shortcuts import render
def upload(request):
    if request.method == "POST":
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_uploaded_file(request.FILES['up_file'])
            return HttpResponseRedirect('/upload_done/')

    form = UploadFileForm()
    return render(request, 'upload_form.html', {'form': form})

This is merely a skeleton. There's no data handling, no error handling, nothing regarding the view after redirection. Even if you are under deadline pressure, you wouldn't be able to manipulate this example without some minimal understanding of the framework. So take the time to go over the tutorial. I can't stretch this enough. It's not long, and very detailed.

edit

I updated the example to a full file-handling example using the django forms. I find it weird to use a form for handling but then saving the file using a function, but seeing as this is how the documentation does it, I'm not gonna go another way

yuvi
  • 18,155
  • 8
  • 56
  • 93
  • Yes, I have tried it at 2nd time & now also with adding 'return render(request, 'upload_form.html',{})', b4 I have not add ',{}' .But still same error **MultiValueDictKeyError (Exception Value: "'up_file'")** The problem is at when retrieving data **foo = request.POST['up_file']** – Swagat Feb 07 '14 at 11:23
  • please read the answer: `"request.FILES, this is where files are sent to"`. Do **foo = request.FILES['up_file']** – yuvi Feb 07 '14 at 11:28
  • Actually I am now trying with `` So I change to **foo = request.POST['up_file']** , Because first I have to solve Post problem – Swagat Feb 07 '14 at 11:31
  • files aren't normal data, so they are not being sent to the POST QueryDict. You will never ever be able to grab a file from `request.POST` because it will never be there. Do you understand that? files are sent to `request.FILES` not to `POST`. There's no problem with POST. It just isn't the part that recieves files. That's the entire point of `multi-part`. – yuvi Feb 07 '14 at 11:33
  • Opps, I am extremely sorry... Its typing mistake. I want to write `` .... – Swagat Feb 07 '14 at 11:36
  • So... use POST. there shouldn't be any problem there. Unless you're doing something else here. – yuvi Feb 07 '14 at 11:38
  • I think I understand the issue. Do a `print request.POST['up_file']`. What do you see in the devserver console? – yuvi Feb 07 '14 at 11:43
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/47013/discussion-between-swagat-and-yuvi) – Swagat Feb 07 '14 at 11:49