4

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

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

4

2 回答 2

8

TL;博士

您应该检查中间件。它允许在视图执行、模板渲染和其他东西之前执行一些代码。

关于中间件的一些话

您可以像这样在脑海中表示中间件:

中间件概念

如您所见,请求(橙色箭头)在执行视图之前会通过每个中间件,然后可以在之后访问每个中间件(例如,如果您想在模板处理之前执行某些操作)。

使用 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

希望这会帮助你:)

于 2013-07-31T18:39:16.717 回答
1

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

于 2013-07-31T19:47:13.220 回答