2013-07-17 23 views
5

Sono totalmente sconcertato su questo, e devo fare qualcosa di incredibilmente stupido. Sto cercando di caricare semplicemente un file su un progetto Django. Il problema sembra essere che nessun dato di modulo viene passato attraverso il server - solo il token csrf. Sto eseguendo Django 1.5.1, python 2.7, virtualenv, su un Mac e utilizzando il server di sviluppo Django integrato.request.FILES sempre vuoto sul caricamento di file

mio modulo HTML è:

{% load url from future %} 

<form enctype="multipart/form-data" method="POST" action="{% url 'showreport' %}"> 
    {% csrf_token %} 
    <label>Upload grade csv file: </label> 
    <input type="hidden" id="testing" value="maybe" /> 
    <input type="file" id="grade_csv" /> 
    <input type="submit" value="Generate Report" /> 
</form> 

Il mio modello:

from django.db import models 

class Document(models.Model): 
file = models.FileField(upload_to='/media/', blank=True, null=True) 

mio forms.py:

from django import forms 
from .models import Document 

class DocumentForm(forms.Form): 
""" 
to handle uploading grades csv file 
""" 
class Meta: 
    models = Document 

mio views.py:

def report(request): 
""" 
Process the CSV file to remove inactive students 
Manipulate to get right JSON format 
Chart the results 
""" 
if request.method == 'POST': 
    form = DocumentForm(request.POST, request.FILES) 
    if form.is_valid(): 
     newfile = Document(file = request.FILES['file']) 
     newfile.save() 

     classdata = {} 
     studentdata = {} 

     return render(request, 'report/showreport.html', { 'classdata': classdata, 'studentdata': studentdata }) 
else: 
    form = UploadFileForm() 

return render(request, 'report/index.html', { 'form': form }) 

Ho trascorso diverse ore a cercare una soluzione, ma nulla sembra funzionare. I have the enctype set correctly (credo), I am using input type 'submit' for the form e I am binding the form data to my model (non importa, poiché request.FILES è vuoto). Ho anche provato a utilizzare un URL diretto nella mia azione modulo (action = '/ report/showreport /') per this Django newbie page, ma questo non ha fatto la differenza. Per quanto posso dire, non ci sono altri script vincolanti per il modulo di invio azione e sovrascrivendo l'azione predefinita.

Mi rendo anche conto che il codice sopra dovrebbe essere più richiesto. FILE ['grades_csv'] per corrispondere all'ID di input del modulo ... eppure anche questo non ha importanza, poiché request.FILES è vuoto.

Nel tentativo di eseguire il debug, ho impostato una traccia pdb prima del if request.method == "POST" nella mia vista. Usando la console, posso vedere che la mia request.POST non include il mio input "testing" nascosto e quella request.FILES è vuota. Quando eseguo questo in un browser, mi riporta alla pagina del mio modulo, essenzialmente dicendo che il mio modulo non è valido. I miei risultati sono PDB qui:

(Pdb) request.FILES 
(Pdb) <MultiValueDict: {}> 
(Pdb) request.POST['testing'] 
(Pdb) *** MultiValueDictKeyError: "Key 'testing' not found in <QueryDict: {u'csrfmiddlewaretoken': [u'0tGCChxa3Po619dCi114Sb9jmWRt82aj']}>" 
(Pdb) request.POST 
<QueryDict: {u'csrfmiddlewaretoken': [u'0tGCChxa3Po619dCi114Sb9jmWRt82aj']}> 

Se provo ad accedere request.FILES nella mia views.py senza verificare se il form è valido, ottengo questo errore:

"Key 'file' not found in <MultiValueDict: {}>" 

Sono perplesso e apprezzare qualsiasi aiuto sul motivo per cui non riesco a farlo funzionare - sembra che dovrebbe essere semplice. Posso creare e scrivere manualmente i file all'interno della mia directory di progetto usando pdb, quindi non credo che le autorizzazioni siano il problema ... il problema è nella forma?

+4

Sembra che il vostro modulo HTML non è presente il nome attributi nei vostri campi di input, provare come Jingo

+4

Alcune cose che sono sospette per me. Gli input del modulo mancano degli attributi 'name'. Stai sottoclassando 'forms.Form' ma hai una classe' Meta' che ti dice 'forms.ModelForm'. Se si intende utilizzare un modulo modello, non è necessario creare un'istanza di un oggetto Documento perché il modulo lo fa per te. –

+0

Genius - grazie! Sarei felice di accettare come risposta se lo invii come uno ... – user

risposta

1

Anch'io ho avuto questo problema e ne sono rimasto perplesso per un po '. Il mio errore era lo stesso: mancavano i campi necessari nel campo input.

Per vedere quali sono i campi in realtà richiesti sono, una bella cosa da fare è, in questo caso:

from base.forms import DocumentForm ## or put whatever the name is of the app, which is unspecified in the question 
print DocumentForm() 

Questo stamperà il codice html di cui avete bisogno, inclusi tutti i tag che questo oggetto richiede. Funzionalità molto accurata che ho perso la prima volta, ma che è delineata in the docs.

+0

Puoi fare un esempio? – shenk

3

Verificare di aver aggiunto enctype proprietà nel tag form.

Esempio da official docs: <form enctype="multipart/form-data" method="post" action="/foo/">

+0

Soluzione perfetta. enctype = "multipart/form-data" ha fatto il trucco per me. Davvero utile. Grazie @Kuznetsov – Doogle

Problemi correlati