2011-10-05 23 views
9

Estoy tratando de escribir un formulario para cargar un archivo con Django. El formulario de administrador funciona bien, pero el problema es que después de hacer clic en enviar en mi formulario, el formulario pierde el archivo que seleccioné (el nombre del archivo desaparece y aparece 'No archivo elegido' junto al botón 'Elegir archivo') y la vista no validará el formulario porque falta el archivo. Mi manejador de formulario/vista/archivo se parece al django example.Cómo cargar un archivo con Django

forms.py

class AttachForm(forms.ModelForm): 
    class Meta: 
      model = Attachment 
      exclude = ('insp', 'contributor', 'date') 

views.py

def handle_uploaded_file(f): 
    destination = open('some/file/name.txt', 'wb+') 
    for chunk in f.chunks(): 
     destination.write(chunk) 
    destination.close() 

def attach(request, insp_id): 
    if request.method == 'POST': 
      form = AttachForm(request.POST, request.FILES) 
      if form.is_valid(): 
        handle_uploaded_file(request.FILES['file']) 
        f = form.save(commit=False) 
        f.contributor = request.user 
        f.insp = insp_id 
        f.save() 
        return HttpResponseRedirect(server + '/inspections/' + str(insp_id) + '/') 
    else: 
      form = AttachForm() 
    return render_to_response('attach.html', locals(), context_instance=RequestContext(request)) 

models.py

class Attachment(models.Model): 
    insp = models.ForeignKey(Inspection) 
    contributor = models.ForeignKey(User, related_name='+') 
    date = models.DateTimeField() 
    title = models.CharField(max_length=50) 
    attachment = models.FileField(upload_to='attachments') 
    def __unicode__(self): 
     return self.title 
    def save(self): 
     if self.date == None: 
      self.date = datetime.now() 
     super(Attachment, self).save() 
    class Meta: 
     ordering = ['-date'] 

attach.html

{% extends "base.html" %} 

{% block title %}Add Attachment{% endblock %} 

{% block content %} 
<h2>Attach File: Inspection {{ insp_id }}</h2> 
<p>This form is used to attach a file to an inspection.</p> 
<form action="." method="POST" autocomplete="off">{% csrf_token %} 
    <table cellspacing="10" cellpadding="1"> 
     {% for field in form %} 
      <tr> 
      <th align="left">    
       {{ field.label_tag }}: 
      </th> 
      <td> 
       {{ field }} 
      </td> 
      <td> 
       {{ field.errors|striptags }} 
      </td> 
     </tr> 
     {% endfor %} 
     <tr><td></td><td><input type="submit" value="Submit"></td></tr> 
    </table> 
</form> 
{% endblock %} 

¿Alguna idea de lo que podría estar haciendo mal?

+2

¿Podría publicar el código de la plantilla también? Una cosa importante para recordar es: "Tenga en cuenta que request.FILES solo contendrá datos si el método de solicitud fue POST y el

que publicó la solicitud tiene el atributo enctype =" multipart/form-data ". De lo contrario, request.FILES será vacío." – LaundroMat

+0

como nota al margen, puede usar las propiedades 'auto_now' y' auto_add_now' ([link to docs] (https://docs.djangoproject.com/en/1.3/ref/models/fields/#datefield)) para DateTimeFields para que no necesite sobreescribir el método de guardar. 'auto_now' actualiza la fecha cada vez que se guarda y' auto_add_now' es solo la fecha de creación, –

+2

Añadiendo ** enctype = "multipart/form-data" ** a la etiqueta del formulario solucionado ese problema, pero ahora está arrojando un MultiValueDictKeyError con descripción " El 'archivo' clave no se encuentra en ]}> " – jdickson

Respuesta

7

Cambie este ...

handle_uploaded_file(request.FILES['file']) 

Para esto ...

handle_uploaded_file(request.FILES['attachment']) 

El archivo se almacena en los datos POST con el nombre de su campo.

Cuestiones relacionadas