假设我想使用我自己创建的 LoginRequiredMixin 和 UserPermissionMixin,并将它们应用于应用程序中的所有 View 。这只是一个例子,我可能还有添加一些上下文或做其他事情的混合。
我可以手动完成,例如这个 View :
class MyCreateView(LoginRequiredMixin, UserPermissionMixin, CreateView)
但是,由于我有很多 View ,而且我可能对某些 View 有其他特定的混合,这会变得困惑且难以管理。
想到的一个解决方案是为通用 View 创建新类:
class DecoratedCreateView(LoginRequiredMixin, UserPermissionMixin, CreateView):
pass
class DecoratedDetailView(LoginRequiredMixin, UserPermissionMixin, DetailView):
pass
class DecoratedUpdateView(LoginRequiredMixin, UserPermissionMixin, UpdateView):
pass
class DecoratedDeleteView(LoginRequiredMixin, UserPermissionMixin, DeleteView):
pass
然后,将这些用作我的通用 View :
class MyCreateView(DecoratedCreateView)
这是一个好方法吗?我是否必须在上面的类中添加任何方法,或者我只是将它们留空并且它会按预期工作? 有没有其他方法可以实现这一点,也许在 urls.py 中?
请您参考如下方法:
你的方法很好。我一直在为一些略有不同的项目这样做:
myapp/views/generic.py
from django.views.generic import (
CreateView as BaseCreateView,
DetailView as BaseDetailView,
UpdateView as BaseUpdateView,
DeleteView as BaseDeleteView,
)
__all__ = ['MyappMixin', 'CreateView', 'DetailView', 'UpdateView', 'DeleteView']
class MyappMixin(LoginRequiredMixin, UserpermissionMixin):
pass
class CreateView(MyappMixin, BaseCreateView):
pass
class DetailView(MyappMixin, BaseDetailView):
pass
class UpdateView(MyappMixin, BaseUpdateView):
pass
class DeleteView(MyappMixin, BaseDeleteView):
pass
myapp/views/base.py
from .generic import CreateView
class MyCreateView(CreateView):
pass
它工作正常,没有太多麻烦,并且允许您在需要时特别轻松地跳过 mixin。
根据用例,另一种解决方案可能是使用 middlewares或 context processors .
class MyMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
is_in_myapp = request.resolver_match.app_name == 'myapp'
if is_in_myapp and not request.user.is_authenticated:
response = HttpResponse("Permission denied", status=403)
else:
response = self.get_response(request)
return response
