将整个django应用限制为普通用户

时间:2019-06-14 06:13:52

标签: django django-views

我未在管理页面上使用django内置管理面板,但我试图添加django-admin之类的功能。我想将普通用户限制为管理页面,为此我尝试了if not request.user.is_superuser,很好。它做得很好,但是在应用程序中可能有数百个功能,我必须将此行添加到每个功能中,我认为这不是最好的主意。 所以有没有想法或解决方案,这样我就可以将整个管理功能仅授予超级用户访问权限,而无需在管理应用程序具有的每个功能/ URL中添加if not request.user.is_superuser

  

views.py

    def a(request):
    if not request.user.is_superuser:
        return redirect('login')
     ..........

    def b(request):
    if not request.user.is_superuser:
        return redirect('login')
    .............

    def c(request):
    if not request.user.is_superuser:
        return redirect('login')
    ...........

    def d(request):
    if not request.user.is_superuser:
        return redirect('login')
    ....

3 个答案:

答案 0 :(得分:1)

自定义装饰器

decorators.py

from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import user_passes_test


def superuser_only(view_func=None, redirect_field_name=REDIRECT_FIELD_NAME,
                          login_url='login'):
    """
    Decorator for views that checks that the user is logged in and is a staff
    member, redirecting to the login page if necessary.
    """
    actual_decorator = user_passes_test(
        lambda u: u.is_active and u.is_superuser,
        login_url=login_url,
        redirect_field_name=redirect_field_name
    )
    if view_func:
        return actual_decorator(view_func)
    return actual_decorator

要将decorator应用于您的所有网址

urls.py

def dec_patterns(patterns):
    decorated_patterns = []
    for pattern in patterns:
        callback = pattern.callback
        pattern.callback = superuser_only(callback)
        pattern._callback = superuser_only(callback)
        decorated_patterns.append(pattern)
    return decorated_patterns

url_patterns = [
    path("my-path/", views.my_view),
]
url_patterns = dec_patterns(url_patterns)

答案 1 :(得分:1)

您可以编写自定义中间件来实现这一目标。

from django.urls import reverse
from django.shortcuts import redirect


class RestrictUserMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if request.path.find("/admin/") > -1:  # restricted admin url for custom admin site
           if not request.user.is_superuser:
              return redirect(reverse('login_url_name'))
        response = self.get_response(request)
        return response

并在SETTINGS文件中使用该中间件:

MIDDLEWARE = [
    # Other middlewares
    'path.to.RestrictUserMiddleware',
]

答案 2 :(得分:0)

您可以将user_passes_test()装饰器与lambda函数一起使用。

from django.contrib.auth.decorators import user_passes_test
from django.http import JsonResponse

# first solution

@user_passes_test(lambda user: user.is_superuser)
def test_func(request):
    return JsonResponse(data={})

# second solution

def check_user(user):
    # you can do more actions here
    return user.is_superuser

@user_passes_test(check_user)
def test_func(request):
    return JsonResponse(data={})

根据您的问题,只需在功能上加上此@user_passes_test(lambda user: user.is_superuser)行即可,这是我的答案的第一个解决方案;如果您需要做更多的事情,可以转到第二个解决方案。