【问题标题】:Does using Django "is_superuser" require additional URL?使用 Django“is_superuser”是否需要额外的 URL?
【发布时间】:2015-02-11 01:20:04
【问题描述】:

我正在为 Django 1.7 项目创建管理界面/仪表板。我没有从头开始创建新的管理应用程序,而是尝试使用 Django 的内置管理站点。我有“root”(超级用户)和“reviewer”(非超级用户)员工帐户。这两个帐户都在默认的“管理员”组中。两个帐户都可以登录管理站点,但某些页面可由 root 和审阅者帐户访问,而对其他页面的访问仅限于超级用户。我创建了以下两个视图:

# mysite/apps/admin/views.py
from django.shortcuts import render
from django.contrib.auth.decorators import user_passes_test

@user_passes_test(lambda u: u.is_staff)
def all_admins(request, template):
    return render(request, template)

@user_passes_test(lambda u: u.is_superuser)
def superuser_only(request, template):
    return render(request, template)

我遇到的问题是,如果我使用审阅者帐户登录并单击“superuser_only”页面的锚点,我会收到以下错误:

Page not found (404)
    Request Method: GET
      Request URL:  http://localhost:8001/accounts/login/?next=/admin/super/
Using the URLconf defined in conf.urls, Django tried these URL patterns, in this order:
^admin/
^admin/all_admins/$ [name='all-admins']
^admin/super/$ [name='superuser-only']
The current URL, accounts/login/, didn't match any of these.

我还需要做些什么来实现这个仅限超级用户的视图和模板,以便在审阅者单击链接时不会发生此错误?

我遵循Django docs instructions 并在 mysite/apps/admin/templates/admin 目录中创建了我自己的 Django 的 base.html、base_site.html 和 index.html 模板副本,然后添加了“all_admins”和“ superuser_only" 锚定到 index.html 页面的底部。

这是我的文件:

# part of mysite/mysite/settings.py
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'apps/admin/templates'),
os.path.join(BASE_DIR, 'apps/admin/templates/admin'),)

# mysite/mysite/urls.py
from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),

    url(r'^admin/all_admins/$',
        'apps.admin.views.all_admins',
        {'template': 'all_admins.html'},
        name='all-admins'),

    url(r'^admin/super/$',
        'apps.admin.views.superuser_only',
        {'template': 'superuser_only.html'},
        name='superuser-only'),
)

【问题讨论】:

    标签: django django-templates django-views


    【解决方案1】:

    然后用户没有通过测试 django 将其重定向到登录页面。此页面的默认 URL 是 /accounts/login/。将LOGIN_URL设置为管理员的登录页面:

    LOGIN_URL = 'admin:login'
    

    或者,如果您在网站上有编外用户,请在urls.py 中设置身份验证网址:

    url('^accounts/', include('django.contrib.auth.urls')),
    

    但这需要您创建多个模板(登录、注销、更改密码等)

    更新:如果您想在登录页面中显示一条消息,那么您可以为管理员创建custom login template。将此行添加到您的 urls.py:

    admin.site.login_template = 'my_login.html'
    

    然后创建从admin/login.html扩展而来的my_login.html模板:

    {% extends 'admin/login.html' %}
    
    {% block content %}
    
        {% if user.is_staff %}
            <p class="errornote">You need to be a superuser to access that page.</p>
        {% endif %}
    
        {{ block.super }}
    
    {% endblock %}
    

    更新 2:如果您不想更改站点范围内的 LOGIN_URL 或通过在 urls.py 中包含 django.contrib.auth.urls 来实现身份验证,那么您可以将 login_url 参数传递给@user_passes_test装饰者:

    @user_passes_test(lambda u: u.is_superuser, login_url='/admin/login/')
    def superuser_only(request, template):
        return render(request, template)
    

    【讨论】:

    • 好收获。这实际上是有效的,因为它可以防止显示错误,但是如果我以审阅者身份登录并且现在单击“仅限超级用户”链接,则不会发生任何事情。我想至少显示一个模板,告诉审阅者他们需要成为超级用户才能访问该页面。也许我必须将视图中的“is_superuser”变量传递给模板,并且只显示不需要查看者成为超级用户的页面的链接?这会让我解决这个问题。
    • 我不太明白。这个放在哪个文件里?如果我将它放在 mysite/apps/admin/templates/admin 目录中的“login.html”文件中,则会在“{% extends... %我创建的 login.html 文件中的 } 标记。
    • 您不应该创建admin/login.html 模板。创建您自己的模板并从login.html 扩展它。然后将admin.site 配置为使用您的模板而不是admin/login.html。查看更新的答案。
    • 不,这仍然不起作用,我不知道为什么。此外,我不确定更改所示的 LOGIN_URL 是否可取,因为我将该设置用于网站的非管理部分。无论如何感谢您的建议。
    • 1.我对其进行了测试,并且效果很好。请显示代码和错误。 2.您可以使用第二个选项而不是更改 LOGIN_URL - 在您的urls.py 中包含“django.contrib.auth.urls”。 3.查看第三个选项的更新答案。
    猜你喜欢
    • 2018-11-21
    • 1970-01-01
    • 2018-07-08
    • 2021-12-19
    • 2011-03-04
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多