@login_required用于多个视图

时间:2014-04-30 21:32:36

标签: django authentication

我可能会有超过20个观看次数。所有这些都要求用户首先进行身份验证。我是否必须将@login_required放在每一个上面?还是有更好的方法?

https://docs.djangoproject.com/en/1.6/topics/auth/default/#django.contrib.auth.decorators.login_required

2 个答案:

答案 0 :(得分:2)

我最终在我的npage app目录中创建了一个名为lockdown.py的新文件并粘贴了this解决方案中的代码:

import re

from django.conf import settings
from django.contrib.auth.decorators import login_required


class RequireLoginMiddleware(object):
    """
    Middleware component that wraps the login_required decorator around
    matching URL patterns. To use, add the class to MIDDLEWARE_CLASSES and
    define LOGIN_REQUIRED_URLS and LOGIN_REQUIRED_URLS_EXCEPTIONS in your
    settings.py. For example:
    ------
    LOGIN_REQUIRED_URLS = (
        r'/topsecret/(.*)$',
    )
    LOGIN_REQUIRED_URLS_EXCEPTIONS = (
        r'/topsecret/login(.*)$',
        r'/topsecret/logout(.*)$',
    )
    ------
    LOGIN_REQUIRED_URLS is where you define URL patterns; each pattern must
    be a valid regex.

    LOGIN_REQUIRED_URLS_EXCEPTIONS is, conversely, where you explicitly
    define any exceptions (like login and logout URLs).
    """
    def __init__(self):
        self.required = tuple(re.compile(url) for url in settings.LOGIN_REQUIRED_URLS)
        self.exceptions = tuple(re.compile(url) for url in settings.LOGIN_REQUIRED_URLS_EXCEPTIONS)

    def process_view(self, request, view_func, view_args, view_kwargs):
        # No need to process URLs if user already logged in
        if request.user.is_authenticated():
            return None

        # An exception match should immediately return None
        for url in self.exceptions:
            if url.match(request.path):
                return None

        # Requests matching a restricted URL pattern are returned
        # wrapped with the login_required decorator
        for url in self.required:
            if url.match(request.path):
                return login_required(view_func)(request, *view_args, **view_kwargs)

        # Explicitly return None for all non-matching requests
        return None

settings.py之后我将其添加到MIDDLEWARE_CLASSES ...

MIDDLEWARE_CLASSES = (
    # ...
    'npage.lockdown.RequireLoginMiddleware',
)

当然,这些线路可以锁定整个网站:

LOGIN_REQUIRED_URLS = (
        r'/(.*)$',
    )
LOGIN_REQUIRED_URLS_EXCEPTIONS = (
    r'/login(.*)$',
    r'/logout(.*)$',
)

答案 1 :(得分:0)

从Django 3+开始,您必须执行以下操作:

步骤1:在yourapp目录中创建一个新文件any.py,并编写以下内容:

import re
from django.conf import settings
from django.contrib.auth.decorators import login_required

//for registering a class as middleware you at least __init__() and __call__()
//for this case we additionally need process_view() which will be automatically called by Django before rendering a view/template

class ClassName(object):
    
    //need for one time initialization, here response is a function which will be called to get response from view/template
    def __init__(self, response):
        self.get_response = response
        self.required = tuple(re.compile(url) for url in settings.AUTH_URLS)
        self.exceptions = tuple(re.compile(url)for url in settings.NO_AUTH_URLS)

    def __call__(self, request):
        //any code written here will be called before requesting response
        response = self.get_response(request)
        //any code written here will be called after response
        return response

    //this is called before requesting response
    def process_view(self, request, view_func, view_args, view_kwargs):
        //if authenticated return no exception
        if request.user.is_authenticated:
            return None
        //if found in allowed exceptional urls return no exception
        for url in self.exceptions:
            if url.match(request.path):
                return None
        //return login_required()
        for url in self.required:
            if url.match(request.path):
                return login_required(view_func)(request, *view_args, **view_kwargs)
        //default case, no exception
        return None

第2步:将以下内容添加到project / settings.py中的Middleware []中,如下所示

MIDDLEWARE = [
    // your previous middleware
    'yourapp.anything.ClassName',
]

第3步:还将以下代码段添加到project / settings.py

AUTH_URLS = (
    //i am disallowing all url
    r'(.*)',
)
NO_AUTH_URLS = (
    r'/admin(.*)$',
)