Django: Как обновить модель после рендеринга вида? - PullRequest
4 голосов
/ 01 июня 2011

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

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

Я посмотрел на сигналы, но безрезультатно.

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

Можно использовать ajax-запрос для запуска обновления или пользовательский тег шаблона для отображения соответствующих полей и обновления их после этого.Мне не нравятся оба, поскольку они перемещают логику приложения в слой представления.Техника ajax также добавляет накладные расходы на второй запрос.

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

Ответы [ 5 ]

8 голосов
/ 01 июня 2011

Здесь не нужно ничего умного. Рендеринг шаблона не обязательно должен быть концом представления - это происходит только тогда, когда вы на самом деле возвращаете это как ответ. Они не должны быть на одном шаге.

Итак:

def my_view(request, params):
    ... do something ...
    response = render_to_response('my_template.html', {'foo': bar'})
    ... do something after rendering ...
    return response

Теперь, если вам нужно сделать это во множестве представлений, вы можете сделать это в декораторе:

def my_decorator(view):
    def my_func(request, params):
        response = view(request, params)
        ... do something after rendering ...
        return response
    return my_func

теперь вы можете украсить ваши виды с помощью @my_decorator, и действие будет выполнено после рендеринга.

... или, мне просто пришло в голову, что если вы хотите сделать это в каждом представлении, вы можете сделать это в промежуточном программном обеспечении (просто определите process-response метод).

Редактировать после комментария Универсальные представления на основе классов используют новый класс TemplateResponse. Вы можете добавлять задачи, которые происходят после фактической визуализации шаблона, с помощью обратного вызова после рендеринга .

0 голосов
/ 01 июня 2011

Если в вашем проекте уже используется сельдерей, вы можете создать задачу для обновления модели и и позвоните

your_task.delay() 

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

Если вы не используете сельдерей, скорее всего, так и будет в будущем:)

0 голосов
/ 01 июня 2011

Django также поставляется со встроенным сигналом request_finished, который отправляется ПОСЛЕ того, как django завершил обработку запроса.

0 голосов
/ 01 июня 2011

Не могли бы вы взять две копии объекта, изменив и сохранив одну, передав другую (неизмененную и устаревшую) одну в представление?

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

0 голосов
/ 01 июня 2011

Получите возвращаемое значение из представления или функции, выполните некоторую обработку, а затем поднимите его в стек.

def foo(*args):
  ret = bar(*args)
  do_something()
  return ret
...