Загрузка файла CSV в django

Я пытаюсь загрузить использование файла 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)

День счастливого Кусочка!

7
задан spyder 17 March 2010 в 18:33
поделиться

5 ответов

Спасибо всем за ваши предложения. Я выбрал несколько новых уловок :) Однако я думаю, что нашел здесь ответ на свою проблему: Загрузка CSV через AJAX Мой "файл сохранения" функция вызывается через запрос Ajax, и похоже, что у ajax есть ограничение, когда «сохранить как диалоговое окно» не отображается независимо от заголовков HTTP.

Я должен был упомянуть, что использую Ajax для вызова этой функции, но мне никогда не приходило в голову, что это может быть проблемой. :) Спасибо, StackOverflow!

3
ответ дан 6 December 2019 в 10:49
поделиться

Если файл статический (т.е. не создан специально для этого запроса), вы все равно не должны обслуживать его через django. Вы должны настроить некоторый путь (например, / static /), который будет обслуживаться вашим веб-сервером, и сохранить все накладные расходы django.

Если файл динамический , есть 2 варианта:

  1. Создать его в памяти и обслуживать из django.
  2. Создайте его на диске и верните ему HttpResponseRedirect, чтобы ваш веб-сервер сам занимался загрузкой (если файл очень большой, вы должны использовать эту опцию).

Что касается динамического обслуживания, я использовал следующий код (который является упрощенной версией 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

9
ответ дан 6 December 2019 в 10:49
поделиться

Вы пытались указать тип содержимого? например.

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
5
ответ дан 6 December 2019 в 10:49
поделиться

Имеет ли значение, если вы не заключите имя файла в двойные кавычки? В примере кода имя файла не цитируется:

response['Content-Disposition'] = 'attachment; filename=foo.xls'

, но в вашем коде есть:

response['Content-Disposition'] = 'attachment; filename="foo.xls"'
0
ответ дан 6 December 2019 в 10:49
поделиться

Томас, я использовал функцию Ajax для сохранения и загрузки этого файла. Оказалось, что в этом случае окно "Сохранить как" не появляется независимо от заголовков. Я просто использовал javascript для загрузки этого файла. window.open("path/to/file"); и все получилось. Я протестировал в IE6 и Firefox, и диалоговое окно появилось.

1
ответ дан 6 December 2019 в 10:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: