Django: 如何在视图渲染后更新模型?

5 投票
5 回答
2410 浏览
提问于 2025-04-16 18:42

我有一个页面,里面显示了一些模型的列表。有些模型的属性需要在页面渲染后更新,也就是说,用户第一次访问时看到的是原始的、没有变化的值,而在后续访问(或者刷新页面)时则会看到更新后的值。

我想用基于类的通用视图来实现这个功能。官方文档提到过“在调用通用视图之前或之后做一些额外的工作”(我强调一下这个“之后”),但是所有给出的例子都是在显示之前就对模型进行了修改。

我也尝试过信号,但没有成功。

创建一个异步任务是一个选择,但因为我只需要更新几个模型中的一个字段(可能一个都不需要),所以这样做似乎有点过于复杂。

可以使用ajax请求来触发更新,或者使用自定义模板标签来显示相关字段并在之后更新它们。但我不喜欢这两种方法,因为它们把应用逻辑放到了视图层。使用ajax技术还会增加第二次请求的开销。

然而,我似乎没有其他选择,难道真的是这样吗?有没有更实用的方法可以在通用视图或请求中插入逻辑,并在模板渲染后执行额外的操作呢?

5 个回答

0

你能不能先复制这个对象两份,修改其中一份并保存,然后把另一份(没修改过的,还是旧的)传给视图呢?

我还没用过基于类的通用视图,所以不能给你一个具体的例子。

0

从视图或函数中获取返回值,进行一些处理,然后再把它传递给上层。

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

这里其实没什么复杂的。渲染一个模板并不意味着这就是视图的结束,真正的结束是在你把这个模板作为响应返回的时候。渲染和返回可以分开来做。

所以:

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 类。你可以通过 后渲染回调 添加在模板真正渲染后要执行的任务。

撰写回答