我创建了自己的登录视图。但是,如果用户直接访问 /admin,则会将其带到管理员登录页面,而不使用我的自定义视图。如何使其重定向到用于除 /admin 以外的所有内容的登录视图?
我创建了自己的登录视图。但是,如果用户直接访问 /admin,则会将其带到管理员登录页面,而不使用我的自定义视图。如何使其重定向到用于除 /admin 以外的所有内容的登录视图?
从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
并带上适当的next
参数。
/admin/
,我仍会看到默认的登录表单,因为 login_required
没有触发。 - Pēteris Caune虽然 @Isaac 的解决方案应该可以拒绝大部分恶意机器人,但它并不能保护专业渗透。当已登录用户尝试登录到管理员时,会收到以下消息:
我们应该改用管理员修饰符来拒绝所有非特权用户:
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib import admin
[ ... ]
admin.site.login = staff_member_required(admin.site.login, login_url=settings.LOGIN_URL)
据我所知,这个装饰器是在1.9版本中添加的。
login_url
参数:
admin.site.login = staff_member_required(admin.site.login, login_url=settings.LOGIN_URL)
- blueyed url(r'^admin/login$', RedirectView.as_view(pattern_name='my_login_page', permanent=True, query_string=True))
url(r'^admin/login/$', RedirectView.as_view(url=settings.LOGIN_URL, permanent=True, query_string=True)),
。 - DanHolá
我找到了一个非常简单的解决方法。
只需要告诉django,管理员登录的url由您自己的登录视图来处理即可。
您只需要修改项目的urls.py文件(请注意,不是应用程序的urls.py文件)
from your_app_name import views
url(r'^admin/', include(admin.site.urls))
url(r'^admin/login/', views.your_login_view),
这是一个示例
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)),
]
我也遇到了同样的问题,试图使用被接受的答案,但是像上面的评论所指出的一样,存在相同的问题。 然后我做了一些不同的事情,如果对某人有帮助,这里把它粘贴出来。
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错误。否则,它会强制您跳转到普通的登录页面(除非您已经登录)。
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真是太棒了。
urlpatterns = patterns('',
...
(r'^admin/', include(admin.site.urls)),
...
)
(r'^admin/', 'myapp.views.myloginview'),
(r'^admin/', include(myapp.urls)),
这是我的解决方案,使用了自定义的AdminSite类:
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
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),
]
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
。