Django - показывать загрузочное сообщение при длительной обработке - PullRequest
6 голосов
/ 30 ноября 2011

Как мне показать , пожалуйста, подождите загрузка сообщения из представления django?

У меня есть представление Django, которое требует значительного времени для выполнения расчетов с большим набором данных.

Во время загрузки процесса я хотел бы предоставить пользователю сообщение обратной связи, например: вращающуюся загрузку анимированного GIF или аналогичного.

Ответы [ 4 ]

3 голосов
/ 30 ноября 2011

После попытки двух разных подходов, предложенных Брэндоном и Муратом, предложение Брэндона оказалось наиболее успешным.

  1. Создайте шаблон оболочки, который включает в себя javascript из http://djangosnippets.org/snippets/679/. Код JavaScript был изменен: (i) для работы без формы (ii), чтобы скрыть индикатор выполнения / отображать результаты, когда «готово» 'возвращается флаг (iii) с URL-адресом обновления JSON, указывающим на представление, описанное ниже

  2. Переместить функцию медленной загрузки в поток. Этому потоку будет передан ключ кеша, и он будет отвечать за обновление кеша статусом прогресса, а затем его результатами. Поток отображает исходный шаблон в виде строки и сохраняет его в кеше.

  3. Создайте представление на основе upload_progress из http://djangosnippets.org/snippets/678/, модифицированного для (i), вместо этого визуализируйте исходный шаблон оболочки, если progress_id = '' (ii) сгенерируйте ключ cache_key, проверьте, существует ли кэш, и если не начинать новый поток (iii) отслеживать ход выполнения потока и по завершении передавать результаты в шаблон оболочки

  4. Шаблон оболочки отображает результаты с помощью document.getElementById('main').innerHTML=data.result

(* проверка того, может ли шаг 4 быть лучше реализован с помощью перенаправления, поскольку представленный шаблон содержит JavaScript, который в данный момент не выполняется document.getElementById('main').innerHTML=data.result)

1 голос
/ 07 апреля 2017

более простой подход - создать страницу ожидания с вашим gif и т. Д., А затем использовать javascript

window.location.href = 'insert results view here';

, чтобы переключиться на представление результатов, с которого начинается длительный расчет. Страница не изменится, пока расчет не закончится. Когда он закончится, будет отображена страница результатов.

1 голос
/ 30 ноября 2011

Вот старина, но может заставить вас двигаться в правильном направлении: http://djangosnippets.org/snippets/679/

0 голосов
/ 30 ноября 2011

Итерация HttpResponse

https://stackoverflow.com/a/1371061/198062

Редактировать:

Я нашел пример отправки больших файлов с помощью django: http://djangosnippets.org/snippets/365/ Затем я смотрю на FileWrapperкласс (django.core.servers.basehttp):

class FileWrapper(object):
    """Wrapper to convert file-like objects to iterables"""

    def __init__(self, filelike, blksize=8192):
        self.filelike = filelike
        self.blksize = blksize
        if hasattr(filelike,'close'):
            self.close = filelike.close

    def __getitem__(self,key):
        data = self.filelike.read(self.blksize)
        if data:
            return data
        raise IndexError

    def __iter__(self):
        return self

    def next(self):
        data = self.filelike.read(self.blksize)
        if data:
            return data
        raise StopIteration

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

class FlushContent(object):
    def __init__(self):
        # some initialization code

    def __getitem__(self,key):
        # send a part of html

    def __iter__(self):
        return self

    def next(self):
        # do some work
        # return some html code
        if finished:
            raise StopIteration

, затем в views.py

def long_work(request):
    flushcontent = FlushContent()
    return HttpResponse(flushcontent)

Редактировать:

Пример кода, все еще не работает:

class FlushContent(object):
    def __init__(self):
        self.stop_index=2
        self.index=0

    def __getitem__(self,key):
        pass

    def __iter__(self):
        return self

    def next(self):
        if self.index==0:
            html="loading"
        elif self.index==1:
            import time
            time.sleep(5)
            html="finished loading"

        self.index+=1

        if self.index>self.stop_index:
            raise StopIteration

        return html
...