gpt4 book ai didi

python - Django:带有 mixins 和调度方法的基于类的 View

转载 作者:行者123 更新时间:2023-12-03 01:48:09 24 4
gpt4 key购买 nike

通常,我使用基于类的 View 的 dispatch 方法来设置一些初始变量或根据用户的权限添加一些逻辑。

例如,

from django.views.generic import FormView
from braces.views import LoginRequiredMixin

class GenerateReportView(LoginRequiredMixin, FormView):
template_name = 'reporting/reporting_form.html'
form_class = ReportForm

def get_form(self, form_class):
form = form_class(**self.get_form_kwargs())
if not self.request.user.is_superuser:
form.fields['report_type'].choices = [
choice for choice in form.fields['report_type'].choices
if choice[0] != INVOICE_REPORT
]
return form

它按预期工作:当匿名用户访问页面时, LoginRequiredMixindispatch 方法被调用,然后将用户重定向到登录页面。

但是如果我想为这个 View 添加一些权限或者设置一些初始变量,例如

class GenerateReportView(LoginRequiredMixin, FormView):

def dispatch(self, *args, **kwargs):
if not (
self.request.user.is_superuser or
self.request.user.is_manager
):
raise Http404
return super(GenerateReportView, self).dispatch(*args, **kwargs)

在某些情况下它不起作用,因为 View 继承的 mixins 的 dispatch 方法尚未被调用。因此,例如,为了能够请求用户的权限,我必须重复 LoginRequiredMixin 的验证:

class GenerateReportView(LoginRequiredMixin, FormView):

def dispatch(self, *args, **kwargs):
if self.request.user.is_authenticated() and not (
self.request.user.is_superuser or
self.request.user.is_manager
):
raise Http404
return super(GenerateReportView, self).dispatch(*args, **kwargs)

这个例子很简单,但有时 mixin 中有一些更复杂的逻辑:它检查权限,进行一些计算并将其存储在类属性中,等等。

现在,我通过从 mixin 复制一些代码(如上面的示例)或通过将代码从 View 的 dispatch 方法复制到另一个 mixin 并在第一个 mixin 之后继承它来解决它一个按顺序执行它们(这不太漂亮,因为这个新的 mixin 仅由一个 View 使用)。

有什么正确的方法可以解决此类问题吗?

最佳答案

我会编写自定义类,它检查所有权限

from django.views.generic import FormView
from braces.views import AccessMixin

class SuperOrManagerPermissionsMixin(AccessMixin):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated():
return self.handle_no_permission(request)
if self.user_has_permissions(request):
return super(SuperOrManagerPermissionsMixin, self).dispatch(
request, *args, **kwargs)
raise Http404 #or return self.handle_no_permission

def user_has_permissions(self, request):
return self.request.user.is_superuser or self.request.user.is_manager

# a bit simplyfied, but with the same redirect for anonymous and logged users
# without permissions


class SuperOrManagerPermissionsMixin(AccessMixin):
def dispatch(self, request, *args, **kwargs):
if self.user_has_permissions(request):
return super(SuperOrManagerPermissionsMixin, self).dispatch(
request, *args, **kwargs)
else:
return self.handle_no_permission(request)

def user_has_permissions(self, request):
return request.user.is_authenticated() and (self.request.user.is_superuser
or self.request.user.is_manager)


class GenerateReportView(SuperOrManagerPermissionsMixin, FormView):
#Remove next two lines, don't need it
def dispatch(self, *args, **kwargs):
#or put some logic here
return super(GenerateReportView, self).dispatch(*args, **kwargs)

类GenerateReportView(SuperOrManagerPermissionsMixin, FormView)的实现不需要重写调度方法

如果你使用多重继承并且其中一个父类需要一些改进,那么最好先改进它。它使代码更加简洁。

关于python - Django:带有 mixins 和调度方法的基于类的 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27824181/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com