Téléchargement de fichiers hébergés

Le problème exposé dans ce sujet a été résolu.

Bonsoir à tous,

Je suis en train de faire quelques essais avec Django. Actuellement, j'ai créé un formulaire pour proposer à l'utilisateur de téléverser un fichier. Je veux ensuite pouvoir proposer ce fichier en téléchargement, et je ne vois pas comment faire. J'ai déjà regardé la documentation et je n'ai pas trouvé d'exemples pour ce que je veux faire. Voici mon modèle :

1
2
3
4
5
6
class Document(models.Model):
   nom = models.CharField(max_length=255)
   file = models.FileField(upload_to="pdf")
   description = models.TextField(null=True)
   def __unicode__(self):
      return "%s" % self.titre

J'arrive à faire le téléversement avec cette vue :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
def ajouter_document(request):
   if request.method == 'POST': 
      form = DocumentForm(request.POST, request.FILES)
      if form.is_valid(): 
         nom = form.cleaned_data['nom']
         file = form.cleaned_data['file']
         description = form.cleaned_data['description']
         envoi = 1
         try:
            doc = Document.objects.get(nom = nom)
         except Document.DoesNotExist:
            doc = Document(nom = nom, file = file, description = description)
            doc.save()
            message = "Le document {a} a bien été ajouté !".format(a = nom)   
         else:
            message = "Le document {a} existe déjà !".format(a = nom)
   return render(request, 'blog/ajouter_doc.html', locals())

Mais c'est ensuite pour proposer le fichier en téléchargement que je ne vois pas comment faire. J'ai esayé d'écrire ça (on passe l'id du fichier en paramètre) :

1
2
3
4
5
6
7
8
def telecharger_document(request, id):
   try:
      f = Document.objects.filter(id = id)[0]
      data = open("%s/%s" % ('media', f.file), 'r')
      response = HttpResponse(data, content_type='application/octet-stream', mimetype='application/%s')
      return response
   except IndexError:
      raise Http404

Avec dans mon settings.py MEDIA_ROOT = 'media/' et MEDIA_URL = '/media/'.

J'espère que vous pourrez m'aider à y voir plus clair.

Merci d'avance pour vos réponses.

+0 -0

Pour télécharger ton fichier j'aurai écris ceci (attention pas testé, donc on peut avoir des erreurs de syntaxe, mais l'idée est là) :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from django.conf import settings
import os

def telecharger_document(request, id):
   f = Document.objects.filter(id = id).first()
   if f is not None:
      my_file = os.path.join(settings.BASE_DIR, settings.MEDIA_ROOT, "pdf", f.name)
      data = open(my_file, 'r')
      response = HttpResponse(data, content_type='application/octet-stream', mimetype='application/%s')
      return response
   else:
      raise Http404

Merci pour ta réponse. J'ai essayé ta solution mais j'obtiens des erreurs.

Tout d'abord sur le mimetype : __init__() got an unexpected keyword argument 'mimetype'. Mais je crois que j'ai lu que le mimetype n'est pas obligatoire, donc je l'ai supprimé.

Ensuite, j'ai une erreur d'encodage 'charmap' codec can't decode byte 0x90 in position 4354: character maps to <undefined>. Je pense que c'est un problème d'encodage. En cherchant sur le net, je vois qu'il faut passer encoding = utf8 comme paramètre à open. Mais j'imagine que ce n'est le cas que lorsque le fichier à télécharger est en UTF-8.

J'essaye quand même, j'obtiens une erreur et je n'arrive pas à la résoudre. Voici l'erreur : 'utf-8' codec can't decode byte 0xf4 in position 82: invalid continuation byte.

Je ne vois pas trop la solution.

+0 -0

Pense à préciser sur quelle ligne tu obtiens tes erreurs.

Sinon, avec quelle version de python travailles-tu ? On dirait que tu es sur une version 2.x

Dans tout les cas, ça devrait marcher un peu mieux avec le code suivant (j'ai surligné mes modifications):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from django.conf import settings
import os

def telecharger_document(request, id):
   f = Document.objects.filter(id = id).first()
   if f is not None:
      my_file = os.path.join(settings.BASE_DIR, settings.MEDIA_ROOT, "pdf", f.name)
      data = open(my_file, 'rb').read()
      response = HttpResponse(data, content_type='application/pdf')
      response["Content-Disposition"] = u"attachment; filename={0}.md".format(f.name)
      return response
   else:
      raise Http404

Merci pour ta réponse. Ton code marche très bien, je l'ai adapté à mon code. Je ne sais pas pourquoi j'avais ce problème d'UTF-8, mais je ne suis pas sur python 2, mais sur python 3.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte