我有一个Django应用程序设置如下:
MyApp
CustomAdmin
urls
models
views
MainApp
settings
urls
wsgi
SomeOtherApp
admin
models
views
现在,在我的MainApp.urls
中,我设置了以下网址:
url(r'^api/admin/', include('CustomAdmin.urls')),
在CustomAdmin
中,我希望有一种机制来检查请求是否由superuser
创建,而不管相关视图如何。如果它是由超级用户创建的,则该请求应由关联的视图函数处理,否则它应该抛出403或类似的错误。
我在Laravel中使用了类似的东西,如下所示
Route::group(
array(
'before' => 'auth.admin',
'prefix' => 'api/admin'
),
function(){
....
});
我不确定Django中是否存在这样的机制。如果有,我该怎么办?
答案 0 :(得分:3)
您可以编写middleware,以便在视图中处理请求之前对请求进行一些处理。在名为middleware.py
的文件中,输入:
from django.contrib.auth.views import redirect_to_login
class AllowSuperUserOnly(object):
def process_request(self, request):
if request.path.startswith('/api/admin/'):
if not request.user.is_superuser:
return redirect_to_login(request.path)
# Continue processing the request as usual:
return None
将中间件添加到settings.py
。它看起来应该类似于:
MIDDLEWARE_CLASSES = (
...
'your_app.middleware.AllowSuperUserOnly',
)
答案 1 :(得分:1)
我认为不可能在包含其他人的url模式上定义它(稍后会对此进行更多测试),但至少可以CustomAdmin.urls
使用user_passes_test
装饰者。
# CustomAdmin/urls.py
from django.contrib.auth.decorators import user_passes_test
from CustomAdmin import views
requires_superuser = user_passes_test(lambda x: x.is_superuser)
urlpatterns = patterns(
'',
url( # with a class based view
r'^$',
requires_superuser(views.SomeView.as_view()),
name='someview'
),
url( # with a functional view
r'^(?P<foo>\w+)/$',
requires_superuser(views.someotherview),
name='someotherview'
),
)
答案 2 :(得分:0)
从ccbv.co.uk和Django Class-bases views docs,dispatch()
是在基于类的视图中调用的第一个方法。
查看课程工作流程
请记住,所有通用视图都会继承View类
中间件是一个很好的解决方案,但如果您不需要预先处理每个请求,您可以使用访问mixin 。
正如我之前所说,dispatch()
是第一个执行的方法,因此您可以重新编写它以授予或拒绝访问视图。
以下是dispatch
默认代码:
def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
你可以写一个mixin
课程:
class SuperuserRequiredMixin(object):
"""
Mixin allows you to require a user with `is_superuser` set to True.
"""
login_url = settings.LOGIN_URL # LOGIN_URL from project settings
raise_exception = False # Default whether to raise an exception to none
redirect_field_name = REDIRECT_FIELD_NAME # Set by django.contrib.auth
def dispatch(self, request, *args, **kwargs):
if not request.user.is_superuser: # If the user is a standard user,
if self.raise_exception: # *and* if an exception was desired
return HttpResponseForbidden() # return a forbidden response.
else:
# otherwise, redirect the user to the login page.
# Also, handily, sets the `next` GET argument for
# future redirects.
path = urlquote(request.get_full_path())
tup = self.login_url, self.redirect_field_name, path
return HttpResponseRedirect("%s?%s=%s" % tup)
return super(SuperuserRequiredMixin, self).dispatch(request, *args, **kwargs)
然后您可以在视图中使用它。我们假设ListView
:
from django.views.generic import ListView
from somewhere import SuperuserRequiredMixin
class MyView(ListView, SuperuserRequiredMixin):
...
# Do what you usually do...
我希望你觉得这很有用。