要在views.py文件中的所有视图中运行的代码

时间:2013-07-31 18:32:25

标签: django django-views django-middleware

views.py文件中的所有视图运行一些代码的最佳方法是什么?

我来自PHP背景,我通常将它放在构造函数/索引位中,以便它始终运行所请求的任何页面。它必须特定于那个views.py文件,但我想检查用户是否可以访问“这个应用程序/模块”并且想要避免在可能的情况下在所有视图上使用装饰器?

2 个答案:

答案 0 :(得分:8)

TL; DR

您应该查看middlewares。它允许在视图执行,模板渲染和其他东西之前执行一些代码。

关于中间件的一些话

您可以像这样代表中间件:

Middleware concept

正如您所看到的,请求(橙色箭头)在执行视图之前遍历每个中间件,然后可以在之后命中每个中间件(例如,如果您想在模板处理之前执行某些操作)。

使用Django 1.10

中间件的结构在Django 1.10中发生了变化,现在由简单的函数表示。例如,这是每个页面的访问计数器:

def simple_middleware(get_response):
    # One-time configuration and initialization.

    def middleware(request):
        try:
            p = Page.objects.get(url=request.path)
            p.nb_visits += 1
            p.save()
        except Page.DoesNotExist: 
            Page(url=request.path).save() 

        response = get_response(request)
        if p:
            response.content += "This page has been seen {0} times.".format(p.nb_visits)

        return response

    return middleware

瞧瞧。

使用Django

这是一个中间件的例子,它会为每次访问页面更新一个计数器(承认页面模型存在两个字段:url和nb_visits)

class StatsMiddleware(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        try:
            p = Page.objects.get(url=request.path)
            p.nb_visits += 1
            p.save()
        except Page.DoesNotExist: 
            Page(url=request.path).save() 

    def process_response(self, request, response):
        if response.status_code == 200:
            p = Page.objects.get(url=request.path)
            # Let's say we add our info after the html response (dirty, yeah I know)
            response.content += u"This page has been seen {0} times.".format(p.nb_visits)
        return response

希望这会对你有所帮助:)。

答案 1 :(得分:1)

中间件是解决方案,但请记住在settings.py中定义中间件的顺序很重要。