Ошибка загрузки файла и ошибка csrf при публикации метода, даже если {% csrf_token %}

Хорошо, я знаю, что у меня много вопросов, но я не нашел ответа на свою проблему. Я новичок в Django, поэтому, пожалуйста, имейте в виду.

Мне нужно сделать, из которого будет загружаться файл:

Вот мой файл upload.py (который является 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)

Теперь мой 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']

Теперь я получаю сообщение об ошибке 403 csrf. Из документа Django я не могу понять, как работают шаблоны (только в состоянии понять, что имя file.html должно совпадать с именем функции views.py).

Пожалуйста, помогите мне, как использовать метод публикации и как загрузить файл. Заранее спасибо...

Я тоже пробовал так (напишите в /home/user/myproject/template/upload_form.html) (Примечание: каталог шаблонов работает правильно)

<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>

& В приведенном выше втором Views.py(т.е. upload_form.py) замените 'Up_file = request.FILES['up_file']' на этот

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

Но получаю ошибку (должен вернуть HttpResponse)


person Swagat    schedule 07.02.2014    source источник
comment
Нет нет, ты делаешь это неправильно. Пожалуйста, просмотрите руководство. Потратьте время, чтобы узнать немного о django. Сразу видно, что ты не знаешь даже основ   -  person yuvi    schedule 07.02.2014
comment
Если метод не POST, вы не даете никакого ответа (что означает, что HttpResponse не возвращается и следующая ошибка). Пожалуйста, прислушайтесь к моему совету и пройдите обучение. Крайний срок или нет, вы никогда не добьетесь прогресса, если не знаете основных основ фреймворка. Вы будете продолжать приходить сюда и копировать код, который не понимаете.   -  person yuvi    schedule 07.02.2014
comment
Кроме того, вы возвращаете рендер в пост без обратной связи. Вы ничего не делаете с формой. Я сомневаюсь, что это то, что вы пытаетесь сделать. Кроме того, csrf должен быть после формы, но не внутри самого тега form.   -  person yuvi    schedule 07.02.2014
comment
Да, я знаю, что вы говорите, но мне нужен только метод публикации для загрузки файла, я вижу csrf внутри формы в этом ответ. Поэтому, пожалуйста, просто скажите мне шаги (т.е. которые будут работать после того, как включают шаблон, представления)   -  person Swagat    schedule 07.02.2014
comment
Смотрите мой ответ. Обратите внимание, что я делаю перенаправление через Django (вместо использования директивы action). Вы всегда должны пытаться сделать как можно больше, используя django. Имея это в виду, было бы проще, если бы вы использовали форму django вместо того, чтобы писать весь этот html   -  person yuvi    schedule 07.02.2014


Ответы (2)


Вот как это должно выглядеть:

upload_form.html:

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

представление (на примере из документов):

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})

Это всего лишь скелет. Там нет обработки данных, нет обработки ошибок, ничего о представлении после перенаправления. Даже если вы поджимаете сроки, вы не сможете манипулировать этим примером без минимального понимания структуры. Поэтому найдите время, чтобы пройтись по руководству. Я не могу растянуть это достаточно. Он не длинный и очень подробный.

изменить

Я обновил пример до полного примера обработки файлов с использованием форм django. Я нахожу странным использовать форму для обработки, а затем сохранять файл с помощью функции, но, учитывая, как это делается в документации, я не собираюсь идти другим путем.

person yuvi    schedule 07.02.2014
comment
Да, я пробовал это во второй раз, а теперь также с добавлением «возврат рендеринга (запрос, «upload_form.html», {})», b4 я не добавлял «, {}». Но все та же ошибка MultiValueDictKeyError (Значение исключения: 'up_file') Проблема заключается в получении данных foo = request.POST['up_file'] - person Swagat; 07.02.2014
comment
пожалуйста, прочитайте ответ: "request.FILES, this is where files are sent to". Выполните foo = request.FILES['up_file'] - person yuvi; 07.02.2014
comment
На самом деле я сейчас пытаюсь использовать <input type="file" name="up_file" >, поэтому я перехожу на foo = request.POST['up_file'] , потому что сначала мне нужно решить проблему публикации. - person Swagat; 07.02.2014
comment
файлы не являются обычными данными, поэтому они не отправляются в POST QueryDict. Вы никогда не сможете получить файл из request.POST, потому что его там никогда не будет. Вы это понимаете? файлы отправляются на request.FILES, а не на POST. С POST проблем нет. Это просто не та часть, которая получает файлы. В этом весь смысл multi-part. - person yuvi; 07.02.2014
comment
Упс, мне очень жаль... Это опечатка. Я хочу написать <input type="text" name="up_file" > .... - person Swagat; 07.02.2014
comment
Итак... используйте POST. там не должно быть проблем. Если вы не делаете что-то еще здесь. - person yuvi; 07.02.2014
comment
Я думаю, что понимаю проблему. Сделайте print request.POST['up_file']. Что вы видите в консоли devserver? - person yuvi; 07.02.2014
comment
давайте продолжим это обсуждение в чате - person Swagat; 07.02.2014

Вы не можете написать HTML непосредственно в своем представлении и ожидать, что он будет автоматически обработан как шаблон. Хотя вы можете передать эту строку в систему рендеринга шаблонов, есть очень веские причины хранить ваши шаблоны и ваши представления отдельно.

Пожалуйста, вернитесь и просмотрите еще раз все примеры, показывающие, как отображать шаблон, и сделайте это вместо жесткого кодирования HTML. Учебник очень хорош и показывает, как именно это сделать, поэтому нет смысла говорить: «Я не могу понять, как работают шаблоны».

Также не следует писать отдельные файлы Python для каждого представления. Вы можете иметь несколько функций просмотра в каждом файле. А когда вы закончите изучение шаблонов, вы можете пойти и прочитать документацию по формам.

person Daniel Roseman    schedule 07.02.2014
comment
Спасибо, @Daniel, мне повезло, что ты снова мне отвечаешь.. Дело в том, что это небольшой проект с несколькими страницами. И главная проблема в том, что у меня крайний срок. Поэтому, если возможно, расскажите мне немного о шаблоне и сообщении формы. - person Swagat; 07.02.2014
comment
Серьезно, это совсем не сложно. Поместите это в файл шаблона и выполните return render(request, 'upload_form.html', {}). - person Daniel Roseman; 07.02.2014
comment
Просто следуйте руководству. - person yuvi; 07.02.2014