Question

Sur Django Python Server, j'ai personnalisé une URL où les utilisateurs peuvent télécharger des fichiers. Maintenant, le problème est que je suis en mesure de télécharger des fichiers lorsque je frappe le navigateur, mais lorsque j'essaie la même chose en utilisant Curl, je ne suis pas en mesure de le faire.

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

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

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> 

Sur le navigateur

enter image description here

Sur le terminal, j'ai essayé

 $ 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

J'ai essayé d'autres variantes mais rien ne semble fonctionner. Aussi quelques autres commandes que j'ai essayées qui ne donnent "aucune erreur de jeton CSRF". J'ai aussi essayé de retirer csrf token Formulaire des inscriptions html file et setting.py Mais rien n'a fonctionné.

Je suis tout nouveau dans Curl et Python tous les deux. Le but principal est de télécharger un fichier à l'aide d'un script Python. Je pensais que si je pouvais télécharger via CURL, les mêmes choses peuvent être reproduites dans Python Script avec la bibliothèque Curl, donc si cela ne fonctionne pas, personne ne peut suggérer un code Python pour télécharger des fichiers sur ce serveur.

Éditer :

$ 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- Réponse d'en-tête (F13 est un nouveau fichier qui n'est pas inclus)

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

Http / 1.1 200 ok
Date: Thu, 07 novembre 2013 23:19:18 GMT Server: Apache / 2.2.22 (Ubuntu)
Vary: Accept-Encoding Content-Length: 1263 Content-Type: Text / HTML; Charset = UTF-8

Exemple de téléchargement de fichiers Django minimal

    <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> 
Était-ce utile?

La solution

Essayez quelque chose comme ceci:

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

Si cela ne fonctionne pas, publiez votre réponse d'en-tête. -i dit à Curl d'imprimer la réponse de l'en-tête.

Autres conseils

Je pense que c'est le jeton CSRF qui manque.

{% csrf_token %}

Regardez Django Docs Protection de contrefaçon de demande de site croisé. C'est un jeton généré pour s'assurer que le formulaire est soumis à partir du même domaine. Vous pouvez soit désactiver la protection CSRF en supprimant la balise du modèle. ou essayer ici sur la façon de le passer à l'aide de curl.

BTW si tout ce que vous voulez, c'est télécharger à l'aide d'un script Python, je recommanderais d'utiliser demandes.

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

Je ne peux pas aider à résoudre cela avec Curl.

Mais si vous pouvez programmer Python3:

Django a une protection pour la contrefaçon de référence du site croisé (CSRF)

Vous devez utiliser le cookie CSRF et le CSRF caché dans la forme.

Vous devez donc d'abord obtenir la page de téléchargement (comme un navigateur), extraire les CSRF et faire le message y compris ces données.

Et le message doit être au format multipartial / forme de format.

Une façon de voir comment est ce format, dans une machine Linux:

1 - Créez une page de téléchargement de django où le point de formulaire Point à (disons) http://127.0.0.1:2222/

2 - Ouvrez un terminal et exécutez: NC -L 127.0.0.1 2222 & 1 | moins

3 - Ouvrez le navigateur dans la page de téléchargement, remplissez le formulaire avec du petit texte à télécharger et appuyez sur le bouton Télécharger. Le navigateur se plaindra, pas de problème ...

4 - Dans le terminal, vous verrez comment le navigateur télécharge le fichier à l'aide du post et du multipart / forme de données

Pour implémenter une solution:

5 - Vérifiez le lien http://blog.spotflux.com/uploading-files-python-3 où il utilise Python3 pour faire le post au format multipartial / format de données.

6 - Vous devrez apporter quelques modifications à cet exemple pour inclure le cookie dans le post.

Utilisez html.parser.htmlparser pour analyser la page HTML.

Cela fonctionne bien, mais je ne peux pas publier le code.

Je n'ai pas essayé d'utiliser les demandes.get () et les demandes.post ().

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top