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)
5 Réponses :
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
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.
Si le fichier est Si le fichier est 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)
Il est généré à la volée pour "cette" demande et stockée temporairement sous / statique /.
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: mais votre code fait: p>
Je devais enfermer le nom de fichier avec des citations pour le faire fonctionner.
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. P>
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! P>
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. P>