Я пытаюсь загрузить использование файла CSV HttpResponse, чтобы удостовериться, что браузер рассматривает его как вложение. Я следую инструкциям, предоставленным здесь, но мой браузер не запрашивает диалоговое окно "Сохранить Как". Я не могу выяснить что не так с моей функцией. Вся справка ценится.
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)
День счастливого Кусочка!
Спасибо всем за ваши предложения. Я выбрал несколько новых уловок :) Однако я думаю, что нашел здесь ответ на свою проблему: Загрузка CSV через AJAX Мой "файл сохранения" функция вызывается через запрос Ajax, и похоже, что у ajax есть ограничение, когда «сохранить как диалоговое окно» не отображается независимо от заголовков HTTP.
Я должен был упомянуть, что использую Ajax для вызова этой функции, но мне никогда не приходило в голову, что это может быть проблемой. :) Спасибо, StackOverflow!
Если файл статический (т.е. не создан специально для этого запроса), вы все равно не должны обслуживать его через django. Вы должны настроить некоторый путь (например, / static /), который будет обслуживаться вашим веб-сервером, и сохранить все накладные расходы django.
Если файл динамический , есть 2 варианта:
Что касается динамического обслуживания, я использовал следующий код (который является упрощенной версией ExcelResponse )
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)
Чтобы использовать его, просто используйте return CSVResponse (...), передавая список списков, список dicts (с одинаковыми ключами), QuerySet, ValuesQuerySet
Вы пытались указать тип содержимого? например.
response['Content-Type'] = 'application/x-download';
Изменить:
Обратите внимание, этот код успешно запускает для меня диалоговое окно «Сохранить как». Обратите внимание, что я указываю «application / x-download» непосредственно в аргументе mimetype. Вы также можете перепроверить свой код и убедиться, что путь к файлу правильный и что FileWrapper () не делает чего-то странного.
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
Имеет ли значение, если вы не заключите имя файла в двойные кавычки? В примере кода имя файла не цитируется:
response['Content-Disposition'] = 'attachment; filename=foo.xls'
, но в вашем коде есть:
response['Content-Disposition'] = 'attachment; filename="foo.xls"'
Томас, я использовал функцию Ajax для сохранения и загрузки этого файла. Оказалось, что в этом случае окно "Сохранить как" не появляется независимо от заголовков. Я просто использовал javascript для загрузки этого файла. window.open("path/to/file"); и все получилось. Я протестировал в IE6 и Firefox, и диалоговое окно появилось.