2010-07-09 3 views
2

J'essaie de créer un script pour télécharger les fichiers téléchargés, sur la machine de l'utilisateur. Le problème est que le téléchargement ne fonctionne tout simplement pas (il me télécharge un fichier vide, ou me donne quelques erreurs).Le fichier de téléchargement Django ne fonctionne pas

la dernière erreur est: qui exerce la contrainte à Unicode: chaîne de besoin ou d'un tampon, FieldFile trouvé

def download_course(request, id): 
    course = Courses.objects.get(pk = id).course 

    path_to_file = 'root/cFolder' 
    filename = course # Select your file here.         
    wrapper = FileWrapper(file(course)) 
    content_type = mimetypes.guess_type(filename)[0] 
    response = HttpResponse(wrapper, content_type = content_type) 
    response['Content-Length'] = os.path.getsize(filename) 
    response['Content-Disposition'] = 'attachment; filename=%s/' % smart_str(course) 

    return response 

comment puis-je déclarer correctement le nom du fichier afin qu'il sache à chaque fois ce fichier à télécharger: la nom de fichier est en fait 'cours' comme déclaré ci-dessus

Merci!

Répondre

5

modifié

Je pense que vous devez extraire path valeur de FileField objet:

def download_course(request, id): 
    course = Courses.objects.get(pk = id).course 

    path = course.path # Get file path 
    wrapper = FileWrapper(open(path, "r")) 
    content_type = mimetypes.guess_type(path)[0] 

    response = HttpResponse(wrapper, content_type = content_type) 
    response['Content-Length'] = os.path.getsize(path) # not FileField instance 
    response['Content-Disposition'] = 'attachment; filename=%s/' % \ 
             smart_str(os.path.basename(path)) # same here 

    return response 

Pourquoi est-ce:

Disons que j'ai (bien, j'ai fait) Modèle:

class DanePracodawcy(DaneAdresowe, DaneKontaktowe): 
    # other fields 
    logo = ImageWithThumbnailsField(upload_to = 'upload/logos/', 
            thumbnail = {'size': (180, 90)}, 
            blank = True) 

ImageWithThumbnailsField est sous-classe de FileField, il se comporte de la même manière. Maintenant, quand je le SELECT:

mysql> select logo from accounts_danepracodawcy; 
+-----------------------------+ 
| logo      | 
+-----------------------------+ 
| upload/logos/Lighthouse.jpg | 
+-----------------------------+ 
1 row in set (0.00 sec) 

il montre (par rapport à MEDIA_ROOT) chemin du fichier stocké. Mais quand j'accéder logo attribut du modèle:

[D:projekty/pracus]|1> from accounts.models import DanePracodawcy 
[D:projekty/pracus]|4> DanePracodawcy.objects.get().logo 
        <4> <ImageWithThumbnailsFieldFile: upload/logos/Lighthouse.jpg> 
[D:projekty/pracus]|5> type(_) 
        <5> <class 'sorl.thumbnail.fields.ImageWithThumbnailsFieldFile'> 

Je reçois par exemple d'un objet. Si je tente de passer à cette instance os.path.getsize:

[D:projekty/pracus]|8> import os.path 
[D:projekty/pracus]|9> os.path.getsize(DanePracodawcy.objects.get().logo) 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 

D:\projekty\pracus\<ipython console> in <module>() 

C:\Python26\lib\genericpath.pyc in getsize(filename) 
    47 def getsize(filename): 
    48  """Return the size of a file, reported by os.stat().""" 
---> 49  return os.stat(filename).st_size 
    50 
    51 

TypeError: coercing to Unicode: need string or buffer, ImageWithThumbnailsFieldFile found 

Je reçois TypeError, comme vous. J'ai besoin Donc chemin du fichier sous forme de chaîne, qui peut être obtenu avec path attribut:

[D:projekty/pracus]|13> os.path.getsize( DanePracodawcy.objects.get().logo.path) 
        <13> 561276L 

Sinon, je pourrais obtenir name attribut et os.path.join avec réglage MEDIA_ROOT:

[D:projekty/pracus]|11> from django.conf import settings 
[D:projekty/pracus]|12> os.path.getsize( os.path.join(settings.MEDIA_ROOT, DanePracodawcy.objects.get().logo.name)) 
        <12> 561276L 

Mais c'est à taper inutile.

La dernière chose à noter: parce path est un chemin absolu, je dois extraire le nom de fichier pour le transmettre à en-tête Content-Disposition:

[D:projekty/pracus]|16> DanePracodawcy.objects.get().logo.path 
        <16> u'd:\\projekty\\pracus\\site_media\\upload\\logos\\lighthouse.jpg' 
[D:projekty/pracus]|17> os.path.basename(DanePracodawcy.objects.get().logo.path) 
        <17> u'lighthouse.jpg' 
+0

nop, le nom du cours est le correspondant du champ 'cours' dans la table – dana

+0

hmm .. c'est tellement bizarre que mon erreur est toujours contrainte à Unicode: besoin de chaîne ou de tampon, FieldFile trouvé. Je ne comprends vraiment pas pourquoi. – dana

+1

Désolé, ma réponse était erronée, j'ai vérifié à nouveau et édité. Maintenant, le code ci-dessus devrait fonctionner comme prévu et j'ai essayé d'expliquer pourquoi cela fonctionne de cette façon. – cji

2

Si vous ne laissez pas l'utilisateur télécharger un fichier généré dynamiquement, je ne vois pas pourquoi vous devez faire tout cela.

Vous pouvez simplement laisser cette vue rediriger vers le chemin approprié, et les en-têtes respectifs sont définis par le serveur desservant les fichiers statiques; généralement apache ou nginx

Je ferais ce point de vue de votre comme suit:

from django.conf import settings 

def download_course(request,id): 
    course = get_object_or_404(Course,id=id) 
    filename = course.course 
    return redirect('%s/%s'%(settings.MEDIA_URL,filename)) 

Enjoy :)

+0

maintenant il dit: objet « FieldFile » n'a pas d'attribut « _default_manager » – dana

Questions connexes