9
votes

Téléchargement d'un fichier CSV à Django

J'essaie de télécharger un fichier CSV à l'aide de HTTPresponse pour vous assurer que le navigateur le traite comme une pièce jointe. Je suis les instructions fournies sur ICI mais mon navigateur n'empelle pas une boîte de dialogue" Enregistrer sous ". Je ne peux pas comprendre ce qui ne va pas avec ma fonction. Toute aide est appréciée.

  dev savefile(request):
        try:
            myfile = request.GET['filename']
            filepath = settings.MEDIA_ROOT + 'results/'
            destpath = os.path.join(filepath, myfile)
            response = HttpResponse(FileWrapper(file(destpath)), mimetype='text/csv' ) 
            response['Content-Disposition'] = 'attachment; filename="%s"' %(myfile)
            return response
        except Exception, err:
            errmsg = "%s"%(err)
            return HttpResponse(errmsg)


0 commentaires

5 Réponses :


5
votes

Avez-vous essayé de spécifier le type de contenu? E.G.

def save_file(request):
    data = open(os.path.join(settings.PROJECT_PATH,'data/table.csv'),'r').read()
    resp = django.http.HttpResponse(data, mimetype='application/x-download')
    resp['Content-Disposition'] = 'attachment;filename=table.csv'
    return resp


3 commentaires

essayé, ne fonctionne toujours pas. Je peux voir la réponse et les en-têtes en Firebug mais je ne reçois pas de boîte de dialogue.


Je l'ai essayé mais je n'ai pas travaillé. S'il vous plaît voir ma réponse, j'ai découvert que la question n'a rien à voir avec Django. Merci


Si vous utilisez ma méthode avec une liaison normale, elle aura le même effet que AJAX en ce qu'elle ne s'éloigne pas de la page en cours.



11
votes

Si le fichier est statique fort> (I.e non généré spécifiquement pour cette demande), vous ne devriez pas le servir à travers Django de toute façon. Vous devez configurer un chemin (comme / statique /) pour être servi par votre serveur Web et enregistrer toute la surcharge de Django.

Si le fichier est dynamique forte>, il y a 2 options: p>

  1. Créez-le en mémoire et le servez de Django. Li>
  2. Créez-le sur le disque et renvoyez-le un httpresponseredirect, de sorte que votre site Web traite avec le téléchargement lui-même (si le fichier est très important, vous devez utiliser cette option). LI> ol>

    comme pour le servir de manière dynamique, j'utilise le code suivant (qui est une version simplifiée de ExcelResponse ) P>

    import StringIO
    from django.db.models.query import ValuesQuerySet, QuerySet
    
    class CSVResponse(HttpResponse):
    
      def __init__(self, data, output_name='data', headers=None, encoding='utf8'):
    
        # Make sure we've got the right type of data to work with
        valid_data = False
        if isinstance(data, ValuesQuerySet):
            data = list(data)
        elif isinstance(data, QuerySet):
            data = list(data.values())
        if hasattr(data, '__getitem__'):
            if isinstance(data[0], dict):
                if headers is None:
                    headers = data[0].keys()
                data = [[row[col] for col in headers] for row in data]
                data.insert(0, headers)
            if hasattr(data[0], '__getitem__'):
                valid_data = True
        assert valid_data is True, "CSVResponse requires a sequence of sequences"
    
        output = StringIO.StringIO()
        for row in data:
            out_row = []
            for value in row:
                if not isinstance(value, basestring):
                    value = unicode(value)
                value = value.encode(encoding)
                out_row.append(value.replace('"', '""'))
            output.write('"%s"\n' %
                         '","'.join(out_row))            
        mimetype = 'text/csv'
        file_ext = 'csv'
        output.seek(0)
        super(CSVResponse, self).__init__(content=output.getvalue(),
                                            mimetype=mimetype)
        self['Content-Disposition'] = 'attachment;filename="%s.%s"' % \
            (output_name.replace('"', '\"'), file_ext)
    


1 commentaires

Il est généré à la volée pour "cette" demande et stockée temporairement sous / statique /.



0
votes

Cela fait-il une différence si vous ne placez pas le nom de fichier dans des guillemets doubles? Le code exemple ne cite pas le nom de fichier: xxx

mais votre code fait: xxx


1 commentaires

Je devais enfermer le nom de fichier avec des citations pour le faire fonctionner.



3
votes

Merci à tous pour vos suggestions. J'ai choisi quelques nouvelles astuces :) Cependant, je pense avoir trouvé la réponse à mon problème ici: téléchargement de CSV via Ajax Ma fonction "SavisesFile" est appelée via une demande Ajax et il apparaît que AJAX a une limitation où "Enregistrer la boîte de dialogue" n'apparaît pas quels sont les en-têtes HTTP.

J'aurais dû mentionner que j'utilise Ajax pour appeler cette fonction, mais cela ne m'a jamais eu pour que cela puisse être un problème. :) Merci Stackoverflow!


0 commentaires

1
votes

Thomas, j'avais utilisé une fonction Ajax pour enregistrer et télécharger ce fichier. Il semble que dans un tel cas, la case "Enregistrer sous" n'apparaîtra pas quelles que soient les en-têtes. J'ai simplement utilisé JavaScript pour télécharger ce fichier. fenêtre.open ("chemin / vers / fichier"); Et ça fait l'affaire. J'ai testé sur IE6 et Firefox et la boîte de dialogue apparaît.


0 commentaires