2011-10-05 30 views
9

Django ile bir dosya yüklemek için form yazmaya çalışıyorum. Yönetici formu gayet iyi çalışıyor, ancak sorun formumda göndermeyi tıkladıktan sonra, form seçtiğim dosyayı kaybediyor (dosya adı kayboluyor ve 'Dosya Seç' düğmesinin yanında 'Dosya seçilmedi' görünür) dosya eksik olduğundan formu doğrulamaz. Formum/görünüm/dosya işleyicim tıpkı django example gibi görünüyor.Django ile dosya yükleme

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 %} 

Ne yapıyorum diye bir fikrim var mı?

+2

Şablon kodunu da gönderir misiniz? Hatırlanması gereken önemli bir nokta şudur: "Request.FILES, yalnızca istek yöntemi POST ve isteği gönderen

, enctype =" multipart/form-data "özelliğine sahipse verileri içerecektir. Aksi takdirde, request.FILES olacaktır. boş." Bir yan not olarak – LaundroMat

+0

, "auto_now" ve "auto_add_now" ([doc to bağlantıları] kullanabilirsiniz (https://docs.djangoproject.com/en/1.3/ref/models/fields/#datefield)) DateTimeFields, böylece kaydetme yöntemini overide etmeniz gerekmez. 'auto_now', her kayıt tarihini günceller ve' auto_add_now' yalnızca oluşturma tarihi, –

+2

Ekleme ** enctype = "multipart/form-data" **, bu sorunu gideren form etiketine eklenmiştir, ancak şimdi bir "MultiValueDictKeyError" ifadesini atar. " Anahtar 'dosya' ]}> " – jdickson

cevap

7

Değişim bu ... Buna

handle_uploaded_file(request.FILES['file']) 

...

handle_uploaded_file(request.FILES['attachment']) 

dosyası alanın adı ile POST verileri saklanır.