Pergunta

No servidor Django Python, eu personalizei um URL onde os usuários podem fazer upload de arquivos. Agora, o problema é que sou capaz de fazer upload de arquivos quando clico no navegador, mas quando tento a mesma coisa usando o CRO, não consigo fazê -lo.

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> 

No navegador

enter image description here

No terminal, eu tentei

 $ 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

Eu tentei algumas outras variações, mas nada parece funcionar. Também alguns outros comandos que tentei que dão "nenhum erro de token CSRF". Eu também tentei remover csrf token formulário de entradas html file e setting.py Mas nada funcionou.

Eu sou todo novo no Curl e Python ambos. O objetivo principal é fazer upload do arquivo usando algum script python. Eu pensei que se eu puder fazer o upload através do CURL, as mesmas coisas podem ser replicadas no script python com a biblioteca Curl; portanto, se isso não estiver funcionando, alguém pode sugerir algum código Python para fazer upload de arquivos para este servidor.

Editar:

$ 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- Resposta do cabeçalho (F13 é um novo arquivo que não está incluído)

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

Http/1.1 200 ok
Data: Qui, 07 de novembro de 2013 23:19:18 Servidor GMT: Apache/2.2.22 (Ubuntu)
Vary: aceitar o comprimento do conteúdo: 1263 tipo de conteúdo: texto/html; charset = utf-8

Exemplo mínimo de upload de arquivo 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> 
Foi útil?

Solução

Tente algo assim:

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

Se não funcionar, poste sua resposta do cabeçalho. -i diz a Curl para imprimir a resposta do cabeçalho.

Outras dicas

Eu acho que é o token do CSRF que está faltando.

{% csrf_token %}

Olhe para Django Docs Proteção de falsificação de solicitação de site cruzado. É um token gerado para garantir que o formulário seja enviado do mesmo domínio. Você pode desativar a proteção do CSRF removendo a tag do modelo. ou tente aqui sobre como passar usando o CURL.

btw se tudo o que você quiser é fazer upload usando um script python que eu recomendaria usar solicitações de.

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

Não posso deixar de resolver isso com o Curl.

Mas se você pode programar Python3:

Django tem uma proteção para falsificação de referência de site transversal (CSRF)

Você precisa usar o cookie CSRF e o CSRF oculto no formulário.

Então você precisa primeiro obter a página de download (como um navegador), extraia os CSRFs e faça a postagem incluindo esses dados.

E a postagem deve estar no formato multipart/formato de dados.

Uma maneira de ver como esse formato é, em uma máquina Linux:

1 - Crie uma página de upload do django onde o formulário aponte para (digamos) http://127.0.0.1:2222/

2 - Abra um terminal e execute: nc -l 127.0.0.1 2222 & 1 | menos

3 - Abra o navegador na página de upload, preencha o formulário com algum texto pequeno para fazer upload e pressione o botão de upload. O navegador vai reclamar, sem problemas ...

4 - No terminal, você verá como o navegador carrega o arquivo usando Post & Multipart/Data -Form

Para implementar uma solução:

5 - Verifique o link http://blog.spotflux.com/uploading-files-python-3 onde usa o Python3 para fazer a postagem no formato multipart/formato de formulário.

6 - Você precisará fazer algumas alterações neste exemplo para incluir o cookie na postagem.

Use html.parser.htmlparser para analisar a página HTML.

Funciona bem, mas não posso postar o código.

Não tentei usar solicitações.get () e requests.post ().

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top