загрузить файл на сервер django с помощью curl

На сервере Python Django я настроил URL-адрес, по которому пользователи могут загружать файлы. Теперь проблема в том, что я успешно могу загружать файлы, когда захожу в браузер, но когда я пытаюсь сделать то же самое с помощью curl, я не могу этого сделать.

views.py

import json

from django.http import HttpResponse
from django.template import Context, RequestContext
from django.shortcuts import render_to_response, get_object_or_404

# -*- coding: utf-8 -*-
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse

from sdm.models import Document
from sdm.forms import DocumentForm

def lists(request):
   # Handle file upload
   if request.method == 'POST':
     form = DocumentForm(request.POST, request.FILES)
     if form.is_valid():
        newdoc = Document(docfile = request.FILES['docfile'])
        newdoc.save()

        # Redirect to the document list after POST
        return HttpResponseRedirect(reverse('sdm:lists'))

else:
    form = DocumentForm() # A empty, unbound form

# Load documents for the list page
documents = Document.objects.all()

# Render list page with the documents and the form
return render_to_response(
    'sdm/lists.html',
    {'documents': documents, 'form': form},
    context_instance=RequestContext(request)
)

........ ........ ........ ........

списки.html

 <!DOCTYPE html>
 <html>
 <head>
    <meta charset="utf-8">
    <title>Minimal Django File Upload Example</title>   
 </head>
 <body>
 <!-- List of uploaded documents -->
 {% if documents %}
    <ul>
    {% for document in documents %}
        <li><a href="{{document.docfile.url }}">{{ document.docfile.name }}</a></li>
    {% endfor %}
    </ul>
 {% else %}
    <p>No documents.</p>
 {% endif %}

    <!-- Upload form. Note enctype attribute! -->
    <form action="{% url sdm:lists %}" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <p>{{form.non_field_errors }}</p>
        <p>{{form.docfile.label_tag }} {{form.docfile.help_text }}</p>
        <p>
            {{ form.docfile.errors }}
            {{ form.docfile }}
        </p>
        <p><input type="submit" name="press" value="Upload" /></p>
    </form>
 </body>
</html> 

В браузере

введите здесь описание изображения

В Терминале я пытался

 $ curl --request PUT --upload-file filename http://wings.spectrumserver/sdm/lists

 $ curl --form upload-file=filename  --form press=Upload 

 http:// wings. spectrumserver/sdm/lists

$ curl --upload-file filename http://wings.spectrumserver/sdm/lists
$ curl --upload-file filename press=upload http://wings.spectrumserver/sdm/lists

$ curl -H 'Expect:' -F data=@filename -F submit=Upload wings.spectrumserver/sdm/lists

// In all cases, No error but no file upload

Я пробовал некоторые другие варианты, но ничего не получается. Также некоторые другие команды, которые я пробовал, выдают «Ошибка токена NO csrf». Я также пытался удалить csrf token записи из html file и setting.py, но ничего не помогло.

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

Изменить:

$ curl -i -F name=press -F f13 wings.spectrumserver/sdm/lists
Warning: Illegally formatted input field!
curl: option -F: is badly used here
curl: try 'curl --help' or 'curl --manual' for more information

Edit2 — ответ заголовка (f13 — новый файл, который не включен)

$ curl -i http://wings.spectrumserver/sdm/lists

HTTP/1.1 200 OK. html; кодировка = utf-8

Пример загрузки минимального файла Django

    <ul>

        <li><a href="/media/documents/2013/10/28/templates.zip">documents/2013/10
    /28/templates.zip</a></li>

        <li><a href="/media/documents/2013/11/07/list">documents/2013/11/07/list</a>
    </li>

        <li><a href="/media/documents/2013/11/07/f1">documents/2013/11/07/f1</a></li>

        <li><a href="/media/documents/2013/11/07/f12">documents/2013/11/07/f12</a></li>

        <li><a href="/media/documents/2013/11/07/hello.html">documents/2013/11
        /07/hello.html</a></li>

    </ul>


    <!-- Upload form. Note enctype attribute! -->
    <form action="/sdm/lists" method="post" enctype="multipart/form-data">

   <!--            
   -->        <p></p>
        <p><label for="id_docfile">Select a file</label> max. 42 megabytes</p>
        <p>

            <input type="file" name="docfile" id="id_docfile" />
        </p>
        <p><input type="submit" name="press" value="Upload" /></p>
    </form>
  </body>
</html> 

person Udit Gupta    schedule 07.11.2013    source источник
comment
вы пытались загрузить с помощью requests.readthedocs.org/en/latest вместо использования curl, если все, что вам нужно, это загрузить с помощью скрипта Python?   -  person yossi    schedule 08.11.2013


Ответы (3)


Попробуйте что-то вроде этого:

curl -i --form docfile=@localfilename http://wings.spectrumserver/sdm/lists

Если не работает, опубликуйте свой ответ заголовка. -i указывает curl напечатать ответ заголовка.

person min    schedule 07.11.2013
comment
попробуй это curl -i --form docfile=@localfilename http://wings.spectrumserver/sdm/lists - person min; 08.11.2013
comment
Можете ли вы помочь мне со скриптом Python для того же .. pycurl и метод, предложенный ниже, кажется, не работает. Может быть, я делаю что-то изношенное, но опять же, если бы вы могли придумать фрагмент, который был бы очень полезен - person Udit Gupta; 08.11.2013
comment
Я не очень хорошо понял, вы можете создать новый вопрос? потому что это разные вопросы. В любом случае подумайте о том, чтобы принять ответ, если он вам помог. - person min; 08.11.2013
comment
stackoverflow.com/questions/19853503/ Пожалуйста, посмотрите здесь. Это действительно было бы большим подспорьем. Спасибо - person Udit Gupta; 08.11.2013

Я думаю, что отсутствует токен CSRF.

{% csrf_token %}

посмотрите документы django защита от подделки межсайтовых запросов . Это токен, сгенерированный для того, чтобы убедиться, что форма отправлена ​​из того же домена. вы можете отключить защиту CSRF, удалив тег из шаблона. или попробуйте здесь, как передать его с помощью curl.

Кстати, если все, что вам нужно, это загрузить с помощью скрипта Python, я бы рекомендовал использовать запросы.

url = 'http://wings.spectrumserver/sdm/lists'
files = {'file': open('file.ext', 'rb')}
r = requests.post(url, files=files)
person yossi    schedule 07.11.2013
comment
Я даже не знаю, что именно?? Подскажите, пожалуйста, что с этим делать? - person Udit Gupta; 08.11.2013
comment
@йосси; но также, если он был в режиме отладки и пытается отправить файл через POST, он получит ошибку, что CSRF отсутствует. Это может быть причиной, но я не уверен. - person min; 08.11.2013
comment
<form action="{% url sdm:lists %}" method="post" enctype="multipart/form-data"> {% csrf_token %} Он уже включил его. - person min; 08.11.2013

Я не могу решить эту проблему с помощью curl.

Но если вы можете запрограммировать python3:

Django имеет защиту от подделки ссылок на сайты (CSRF)

Вам нужно использовать файл cookie CSRF и скрытый CSRF в ФОРМЕ.

Итак, вам нужно сначала ПОЛУЧИТЬ страницу загрузки (например, браузер), извлечь CSRF и сделать POST, включая эти данные.

И POST должен быть в формате multipart/form-data.

Один из способов увидеть, как выглядит этот формат на машине с Linux:

1. Создайте страницу загрузки Django, где форма ACTION указывает (скажем) на http://127.0.0.1:2222/< /а>

2 - Откройте терминал и выполните: nc -l 127.0.0.1 2222 &1 | меньше

3 - Откройте браузер на странице загрузки, заполните форму небольшим текстом для загрузки и нажмите кнопку загрузки. Браузер будет жаловаться, нет проблем...

4 - В терминале вы увидите, как браузер загружает файл с помощью POST и multipart/data-form

Чтобы реализовать решение:

5 – Проверьте ссылку http://blog.spotflux.com/uploading-files-python-3, где он использует python3 для создания POST в формате multipart/form-data.

6. Вам нужно будет внести некоторые изменения в этот пример, чтобы включить файл cookie в сообщение.

Используйте html.parser.HTMLParser для анализа HTML-страницы.

Он работает нормально, но я не могу опубликовать код.

Я не пытался использовать запросы.get() и запросы.post().

person user7886623    schedule 18.04.2017