Удаление tmp файла после возврата HttpResponse в django - PullRequest
9 голосов
/ 27 августа 2010

Я использую следующий код django / python для потоковой передачи файла в браузер:

wrapper = FileWrapper(file(path))
response = HttpResponse(wrapper, content_type='text/plain')
response['Content-Length'] = os.path.getsize(path)
return response

Есть ли способ удалить файл после возвращения ответа? Используя функцию обратного вызова или что-то? Я мог бы просто создать cron для удаления всех файлов tmp, но было бы лучше, если бы я мог передавать файлы и удалять их из того же запроса.

Ответы [ 5 ]

10 голосов
/ 27 августа 2010

Вы можете использовать NamedTeoraryFile:

from django.core.files.temp import NamedTemporaryFile
def send_file(request):
    newfile = NamedTemporaryFile(suffix='.txt')
    # save your data to newfile.name
    wrapper = FileWrapper(newfile)
    response = HttpResponse(wrapper, content_type=mime_type)
    response['Content-Disposition'] = 'attachment; filename=%s' % os.path.basename(modelfile.name)
    response['Content-Length'] = os.path.getsize(modelfile.name)
    return response

Временный файл должен быть удален после удаления объекта newfile.

2 голосов
/ 16 февраля 2012

Это просто использование обычного подхода python (очень простой пример):

# something generates a file at filepath

from subprocess import Popen

# open file
with open(filepath, "rb") as fid:
    filedata = fid.read()

# remove the file
p = Popen("rm %s" % filepath, shell=True)

# make response
response = HttpResponse(filedata, content-type="text/plain")

return response
2 голосов
/ 27 августа 2010

В основном мы используем для этого периодические задания cron.

У Django уже есть одно задание cron для очистки потерянных сеансовИ вы уже запускаете его, верно?

См. http://docs.djangoproject.com/en/dev/topics/http/sessions/#clearing-the-session-table

Вам нужна еще одна команда, такая как эта, в вашем приложении, которая очищает старые файлы.1012 * Также, возможно, вы не отправляете этот файл из Django.Иногда вы можете повысить производительность, создав файл в каталоге, используемом Apache, и перенаправив его на URL-адрес, чтобы файл мог обслуживаться Apache за вас.Иногда это быстрее.Однако он не справляется с очисткой.

1 голос
/ 19 декабря 2013

Для будущих ссылок: у меня только что был случай, когда я не мог использовать временные файлы для загрузки.Но я все еще должен был удалить их после этого;вот как я это сделал (я действительно не хотел полагаться на работу cron, сельдерея или wossnames, это очень маленькая система, и я хотел, чтобы она оставалась такой).

def plug_cleaning_into_stream(stream, filename):
    try:
        closer = getattr(stream, 'close')
        #define a new function that still uses the old one
        def new_closer():
            closer()
            os.remove(filename)
            #any cleaning you need added as well
        #substitute it to the old close() function
        setattr(stream, 'close', new_closer)
    except:
        raise

, а затемЯ просто взял поток, использованный для ответа, и подключился к нему.

def send_file(request, filename):
    with io.open(filename, 'rb') as ready_file:
        plug_cleaning_into_stream(ready_file, filename)
        response = HttpResponse(ready_file.read(), content_type='application/force-download')
        # here all the rest of the heards settings
        # ...
        return response

Я знаю, что это быстро и грязно, но это работает.Я сомневаюсь, что это будет продуктивно для сервера с тысячами запросов в секунду, но это не мой случай здесь (максимум несколько десятков в минуту).

РЕДАКТИРОВАТЬ: забыл уточнить, что я имел дело с очень очень большойфайлы, которые не могли поместиться в памяти во время загрузки.Вот почему я использую BufferedReader (что под io.open())

1 голос
/ 27 августа 2010

Один из способов - добавить представление для удаления этого файла и вызвать его из на стороне клиента с помощью асинхронного вызова (XMLHttpRequest). Вариант этого будет включать в себя сообщение от клиента об успехе, чтобы сервер мог пометить этот файл для удаления и периодически очищать его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...