Отображение содержимого (а не сохранения) загруженного файла с помощью Django - PullRequest
4 голосов
/ 26 апреля 2010

Как получить форму с FileField, в которой загруженный файл не будет сохранен, а вместо этого будет извлечено и отображено его текстовое содержимое?

1 Ответ

9 голосов
/ 26 апреля 2010

Документы: http://docs.djangoproject.com/en/dev/topics/http/file-uploads/

Короткая версия:

  1. Ваша форма для загрузки должна иметь поле forms.FileField.
  2. Когда форма отправлена, она переходит на URL, который переходит к функции просмотра, которую вы написали. Эта функция просмотра принимает HttpRequest (обычно называется request).
  3. Получить файл из request.FILES[].

Например, если ваша форма имеет:

upFile = forms.FileField

Тогда ваше представление может получить к файлу:

def uploadView(request):
    upFile = request.FILES["upFile"]

где upFile - это UploadedFile объект, который не похож на файл. UploadedFile обладает следующими свойствами:

  • name: имя загружаемого файла
  • size: размер в байтах

и следующие методы:

  • read(): прочитать весь файл и вернуть в виде строки. Вероятно, хорошо для вас, но не рекомендуется для файлов более 2,5 МБ.
  • multiple_chunks(): возвращает True, если файл должен обрабатываться как несколько кусков.
  • chunks(): возвращает генератор (используйте его как итератор), который возвращает данные файла по одному фрагменту за раз.

Итак, продолжая пример, если вы просто хотите сохранить файл на диск, вы можете написать:

outFile = open("/tmp/uploadTest.txt", "w")
if not upFile.multiple_chunks():
    outFile.write(upFile.read())
else:
    for chunk in upFile.chunks():
        outFile.write(chunk)
outFile.close()

В вашем случае вы могли бы просто показать сообщение об ошибке и отменить файл, если multiple_chunks() вернет True, поскольку вы, вероятно, не хотите помещать более 2,5 МБ текста на свою страницу.

РЕДАКТИРОВАТЬ: Ну, ваш вопрос полностью изменился, когда я писал свой ответ. Итак, объясняя, как поместить содержимое файла на страницу, и предполагая, что размер файла не превышает 2,5 МБ, ваша функция просмотра может выглядеть следующим образом:

def uploadView(request):
    upFile = request.FILES["upFile"]
    context = {}
    if upFile.multiple_chunks():
        context["uploadError"] = "Uploaded file is too big (%.2f MB)." % (upFile.size,)
    else:
        context["uploadedFile"] = upFile.read()
    return render_to_response('fileUploadPage.html', context)

Добавление, конечно, любой другой необходимой вам обработки.

Тогда ваш шаблон fileUploadPage.html должен иметь где-то:

<div id="uploaded">
    {% if uploadError %}
    <span class="error">{{ uploadError }}</span>
    {% else %}
    {{ uploadedFile }}
    {% endif %}
</div>

РЕДАКТИРОВАТЬ 2: Доминик имеет хорошую точку. Вот общий код шаблона для правильной установки тега form. Используйте это в шаблоне, который имеет форму:

<form method="post" action="{% url uploadFile %}"
{% if form.is_multipart %}
    enctype="multipart/form-data"
{% endif %}>
{{ form }}
</form>

В вашем случае, поскольку вы знаете, что в форме будет файл, вы можете потерять блок if:

<form method="post" action="{% url uploadFile %}" enctype="multipart/form-data">
{{ form }}
</form>

Примечание. Команда {% url ___ %} вставит URL-адрес для представления или именованный URL-адрес. Параметр является либо именем функции представления, используемой в вашем файле urls.py, либо именем, данным объекту url, например:

urlpatterns = patterns('',
    url('^uploadform$', 'myapp.views.uploadFormView', name='uploadForm'),
    url('^upload$', 'myapp.views.uploadView', name='uploadFile'),
    # ...
)
...