Frage

Auf Django Python Server habe ich eine URL angepasst, in der Benutzer Dateien hochladen können. Das Problem ist nun, dass ich erfolgreich in der Lage bin, Dateien hochzuladen, wenn ich auf den Browser drücke, aber wenn ich es mit Curl versuche, kann ich dies nicht tun.

Ansichten.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)
)

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

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

Auf dem Browser

enter image description here

Am Terminal versuchte ich es

 $ 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

Ich habe einige andere Variationen ausprobiert, aber nichts scheint zu funktionieren. Auch einige andere Befehle, die ich ausprobiert habe, die "keinen CSRF -Token -Fehler" gibt. Ich habe auch versucht zu entfernen csrf token Einträge Form html file und setting.py Aber nichts hat funktioniert.

Ich bin alle neu bei Curl und Python beides. Der Hauptzweck besteht darin, Datei mithilfe eines Python -Skripts hochzuladen. Ich dachte, wenn ich Curl hochladen kann, kann dieselbe Dinge im Python -Skript mit Curl -Bibliothek repliziert werden. Wenn dies nicht funktioniert, kann jemand einen Python -Code vorschlagen, um Dateien auf diesen Server hochzuladen.

Bearbeiten :

$ 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- Header-Antwort (F13 ist eine neue Datei, die nicht enthalten ist)

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

Http/1.1 200 ok
Datum: Thu, 07. November 2013 23:19:18 GMT Server: Apache/2.2.22 (Ubuntu)
Variieren: Inhaltslänge von Akzeptieren: 1263 Inhaltstyp: text/html; charset = utf-8

Minimaler Django -Datei -Upload -Beispiel

    <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> 
War es hilfreich?

Lösung

Probieren Sie so etwas aus:

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

Wenn nicht funktioniert, veröffentlichen Sie Ihre Header -Antwort. -i fordert Curl an, die Header -Antwort zu drucken.

Andere Tipps

Ich denke, es ist das CSRF -Token, das fehlt.

{% csrf_token %}

Schauen Sie sich Django Docs an Cross Site -Anfrage Fälschungsschutz. Es ist ein Token, das generiert wird, um sicherzustellen, dass das Formular aus derselben Domäne eingereicht wird. Sie können entweder den CSRF -Schutz deaktivieren, indem Sie das Tag aus der Vorlage entfernen. oder Versuche hier Wie man es mit Curl passt.

Übrigens, wenn alles, was Sie wollen, mithilfe eines Python -Skripts hochladen, das ich empfehlen würde Anfragen.

url = 'http://wings.spectrumserver/sdm/lists'
files = {'file': open('file.ext', 'rb')}
r = requests.post(url, files=files)

Ich kann nicht helfen, dies mit Curl zu lösen.

Aber wenn Sie Python3 programmieren können:

Django hat einen Schutz für Cross Site Reference Forgery (CSRF)

Sie müssen das CSRF -Cookie und das versteckte CSRF in der Form verwenden.

Sie müssen also zuerst die Download -Seite (wie ein Browser) erhalten, die CSRFs extrahieren und den Beitrag inklusive dieser Daten erstellen.

Und der Beitrag muss im Mehrteil-/Formdatenformat sein.

Eine Möglichkeit zu sehen, wie dieses Format in einer Linux -Maschine ist:

1 - Erstellen Sie eine Django -Upload -Seite, auf der die Formular Aktion zeigt (sagen wir) http://127.0.0.1:2222/

2 - Öffnen Sie ein Terminal und führen Sie aus: NC -L 127.0.0.1 2222 & 1 | weniger

3 - Öffnen Sie den Browser auf der Upload -Seite, füllen Sie das Formular mit einem kleinen Text aus und drücken Sie die Upload -Taste. Der Browser wird sich beschweren, kein Problem ...

4 - Im Terminal sehen Sie, wie der Browser die Datei mithilfe von Post & Multipart/Data -Form hochlädt

Um eine Lösung zu implementieren:

5 - Überprüfen Sie den Link http://blog.spotflux.com/uploading-files-python-3 Wo es Python3 verwendet, um den Beitrag im Mehrteil-/Formdatenformat zu erstellen.

6 - Sie müssen in diesem Beispiel einige Änderungen vornehmen, um den Cookie in den Beitrag aufzunehmen.

Verwenden Sie html.parser.htmlParser, um die HTML -Seite zu analysieren.

Es funktioniert gut, aber ich kann den Code nicht posten.

Ich habe nicht versucht, Requests.get () und Requests.Post () zu verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top