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

发布于 2024-11-10 14:39:11 字数 576 浏览 3 评论 0原文

我有一个显示模型列表的视图。渲染视图后,某些模型的某些属性需要更新:也就是说,用户希望在第一次访问时看到原始的、未更改的值,并在连续访问时(或在页面重新加载时)看到更新的值。

我认为我可以通过基于类的通用视图来实现这一点。 官方文档暗示“在调用通用视图之前或之后做一些额外的工作”(强调我的),但是给出的所有示例都会在显示之前影响模型。

我查看了信号,但无济于事。

生成异步任务是一种选择,但是,由于我需要做的就是更新几个模型(可能有一个或没有)中的字段并保存它们,因此对于手头的任务来说似乎有点过分了。

可以使用 ajax 请求来触发更新,或者使用自定义模板标签来显示相关字段并随后更新它们。我不喜欢两者,因为它们将应用程序逻辑移至视图层。 ajax 技术还增加了第二个请求的开销。

然而,我似乎没有其他选择,不是吗?是否有更实用的技术可以插入通用视图或请求并在模板呈现后执行额外的逻辑?

I have a view that displays a list of models. Some of the properties of some of the models need to be updated after the view has been rendered: that is, the user is expected to see the original, unchanged values on first visit and the updated values on successive visits (or upon page reload).

I thought I could achieve this with class-based generic views. The official documentation hints at "doing some extra work before or after calling the generic view" (emphasis mine), but all examples given affect the models before it is displayed.

I looked into signals, but to no avail.

Spawning an asynchronous task is an option, but, since all I need to do is update a field in a few models (likely one or none) and save them, it seems overkill for the task at hand.

One could use an ajax request to trigger the update, or a custom template tag to display the relevant fields and update them thereafter. I dislike both, as they move application logic into the view layer. The ajax technique also adds the overhead of a second request.

Yet, I seem to have no other choices, or do I? Is there a more practical technique for plugging into the generic view or the request and execute extra logic after the template has been rendered?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

白况 2024-11-17 14:39:11

这里不需要任何聪明的东西。渲染模板不一定是视图的结束 - 只有当您实际返回该视图作为响应时才会出现。他们不必处于同一步骤。

所以:

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 类。您可以使用 渲染后回调

There's no need for anything clever here. Rendering a template doesn't need to be the end of the view - that only comes when you actually return that as a response. They don't have to be in the same step.

So :

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

Now, if you need to do this in a lot of views, you might want to do it in a decorator:

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

now you can decorate your views with @my_decorator and the action will be performed after rendering.

... or, it just occurred to me, if you want to do it in every view, you could do it in a middleware (just define the process-response method).

Edit after comment Class-based generic views use the new TemplateResponse class. You can add tasks that happen after the template is actually rendered with a post-render callback.

八巷 2024-11-17 14:39:11

捕获视图或函数的返回值,进行一些处理,然后将其放入堆栈。

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

Catch the return value from the view or function, do some processing, then kick it up the stack.

def foo(*args):
  ret = bar(*args)
  do_something()
  return ret
心作怪 2024-11-17 14:39:11

您能否获取该对象的两份副本,修改并保存一份,同时将另一份(未修改且过时的)传递给视图?

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

Could you grab two copies of the object, modifying and saving one while passing the other (unmodified and outdated) one to the view?

I haven't used class-based generic views yet, so I can't give you a specific example.

宛菡 2024-11-17 14:39:11

Django 还附带了一个 内置信号 request_finished,即在 django 处理完请求后发送。

Django also comes with a built-in signal request_finished, that is sent AFTER django finished processing the request.

风向决定发型 2024-11-17 14:39:11

如果您的项目已经使用 celery,您可以创建一个任务来更新模型并
并调用

your_task.delay() 

您可以使用倒计时参数来指定启动任务之前经过的时间。

如果您不使用芹菜,那么您将来很可能会使用:)

If your project already use celery, you could create a task to update the model and
and call

your_task.delay() 

You could use the countdown argument to specify an elapsed before launching the task.

If you are not using celery chances are that you will in the future :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文