我怎么能不使用Django的管理员登录视图?

时间:2011-07-21 16:13:42

标签: django django-admin django-authentication

我创建了自己的登录视图。但是,如果用户直接访问/ admin,则会将其带到管理员登录页面,而不会使用我的自定义视图。如何将其重定向到用于/ admin的所有内容的登录视图?

10 个答案:

答案 0 :(得分:51)

http://djangosnippets.org/snippets/2127/ - 用login_required包装管理员登录页面。例如,在urls.py

from django.contrib.auth.decorators import login_required
from django.contrib import admin
admin.autodiscover()
admin.site.login = login_required(admin.site.login)

你可能已经有两条线,甚至可能是第一条线;添加第四行会导致任何可能会使admin.site.login函数重定向到LOGIN_URL的{​​{1}} next个参数。

答案 1 :(得分:7)

我发现上面的答案不尊重" next"查询参数正确。

解决此问题的简单方法是使用简单的重定向。在您网站的网址文件中,立即之前包括管理网址,请输入如下所示的行:

   url(r'^admin/login$', RedirectView.as_view(pattern_name='my_login_page', permanent=True, query_string=True))

答案 2 :(得分:4)

HOLA
我找到了一个非常简单的解决方案 告诉django管理员登录的URL由您自己的登录视图处理

您只需要修改项目的urls.py文件(注意,而不是应用程序)

  1. 在PROJECT文件夹中找到文件urls.py。
  2. 将此行添加到导入部分
    from your_app_name import views
  3. 找到此行
    url(r'^admin/', include(admin.site.urls))
  4. 在上面添加以下内容 url(r'^admin/login/', views.your_login_view),
  5. 这是一个例子

        from django.conf.urls import include, url
        from django.contrib import admin
    
        from your_app import views
    
        urlpatterns = [
            url(r'^your_app_start/', include('your_app.urls',namespace="your_app_name")),
    
            url(r'^admin/login/', views.your_app_login),
            url(r'^admin/', include(admin.site.urls)),
        ]
    

答案 3 :(得分:4)

虽然@ Isaac的解决方案应该拒绝大多数恶意机器人,但它并没有为职业渗透提供保护。当登录用户尝试登录管理员时收到以下消息:

Django re-login prompt

我们应该使用admin decorator来拒绝所有非特权用户:

from django.contrib.admin.views.decorators import staff_member_required
from django.contrib import admin
[ ... ]
admin.site.login = staff_member_required(admin.site.login)

据我所知,装饰师在1.9中是added

答案 4 :(得分:3)

http://blog.montylounge.com/2009/07/5/customizing-django-admin-branding/web archive)

我正在努力解决这个问题,我找到了这个家伙博客的解决方案。基本上,覆盖管理模板并使用您自己的模板。简而言之,只需在/ path-to-project / templates / admin /中创建一个名为login.html的文件,它将替换管理员登录页面。您可以复制原始文件(django / contrib / admin / templates / login.html)并修改一行或两行。如果您想完全取消默认登录页面,可以执行以下操作:

{% extends "my-login-page.html" %}

就是这样。一个文件中的一行。 Django很棒。

答案 5 :(得分:2)

在您的ROOT_URLCONF文件中(默认情况下,它是项目根文件夹中的urls.py),是否有这样的行:

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

如果是这样,您需要将include(admin.site.urls)替换为您创建的自定义视图:

(r'^admin/', 'myapp.views.myloginview'),

或者如果你的应用有自己的urls.py,你可以像这样包含它:

(r'^admin/', include(myapp.urls)),

答案 6 :(得分:2)

我遇到了同样的问题,尝试使用已接受的answer,但问题与comment above中指出的问题相同。 然后我做了一些与众不同的事情,如果这对某人有帮助,可以粘贴在这里。

def staff_or_404(u):
    if u.is_active:
        if u.is_staff:
            return True
        raise Http404()
    return False

admin.site.login = user_passes_test(
        staff_or_404,
    )(admin.site.login)

这个想法是,如果用户登录并尝试访问管理员,那么他将获得404.否则,它将强制您进入正常的登录页面(除非您已经登录)

答案 7 :(得分:1)

这是我使用custom AdminSite class的解决方案:

class AdminSite(admin.AdminSite):

    def _is_login_redirect(self, response):
        if isinstance(response, HttpResponseRedirect):
            login_url = reverse('admin:login', current_app=self.name)
            response_url = urllib.parse.urlparse(response.url).path
            return login_url == response_url
        else:
            return False

    def admin_view(self, view, cacheable=False):
        inner = super().admin_view(view, cacheable)

        def wrapper(request, *args, **kwargs):
            response = inner(request, *args, **kwargs)
            if self._is_login_redirect(response):
                if request.user.is_authenticated():
                    return HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
                else:
                    return redirect_to_login(request.get_full_path(), reverse('accounts_login'))
            else:
                return response

        return wrapper

答案 8 :(得分:0)

您可以将管理员登录URL重定向到auth登录视图:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('', include('your_app.urls')),
    path('accounts/', include('django.contrib.auth.urls')),
    path('admin/login/', RedirectView.as_view(url='/accounts/login/?next=/admin/', permanent=True)),
    path('admin/', admin.site.urls),
]

答案 9 :(得分:0)

截至2020年8月,django.contrib.admin.sites.AdminSite具有login_template属性。因此,您可以仅继承AdminSite并指定自定义模板,即

class MyAdminSite(AdminSite):
    login_template = 'my_login_template.html'

my_admin_site = MyAdminSite()

然后仅在各处使用my_admin_site而不是admin.site