Django动态扩展基于类的视图

Django动态扩展基于类的视图,django,django-guardian,Django,Django Guardian,在Django的基于类的视图中,是否有一种很好的方法可以动态选择要扩展的视图 现在,我有两个视图(更新和视图),如下所示,我希望将它们折叠为1: from django.views.generic import UpdateView, DetailView from guardian.mixins import PermissionRequiredMixin class MyUpdateView(PermissionRequiredMixin, UpdateView): model

在Django的基于类的视图中,是否有一种很好的方法可以动态选择要扩展的视图

现在,我有两个视图(更新和视图),如下所示,我希望将它们折叠为1:

from django.views.generic import UpdateView, DetailView
from guardian.mixins import PermissionRequiredMixin
 
class MyUpdateView(PermissionRequiredMixin, UpdateView):
    model = MyModel
    permission_required = 'MyApp.change_mymodel'
    template_name = "MyApp/update.html"
    fields = ["name", "Type", "description"]

class MyDetailView(PermissionRequiredMixin, DetailView):
    model = MyModel
    permission_required = 'MyApp.view_mymodel'
    template_name = "MyApp/view.html"
我想做的是有一个视图和一个url,当访问视图时,如果用户有更改权限,它应该使用UpdateView,如果他们有查看权限,则使用DetailView,如果他们都没有显示某种错误

有什么办法可以让它发挥作用吗

编辑:最终解决方案:

class CombinedView(PermissionRequiredMixin, DetailView, UpdateView):
model = MyModel
fields = ["name", "Type", "description"]

def get_required_permissions(self, request=None):
    if (self.request.user).has_perm('MyApp.change_mymodel', self.get_object()):
        return ['MyApp.change_mymodel']
    return ['MyApp.view_mymodel']

def get_template_names(self):
    if (self.request.user).has_perm('MyApp.change_mymodel', self.get_object()):
        return ["MyApp/update.html"]
    return ["MyApp/view.html"]

重写
get\u template\u names()
方法和
get\u required\u permissions()
方法,如下所示:

class CombinedView(PermissionRequiredMixin, DetailView, UpdateView):
    model = MyModel
    fields = ["name", "Type", "description"]

    def get_required_permissions(self, request=None):  # alternate to `permission_required`
        if self.request.method == 'POST':
            return ['MyApp.change_mymodel']
        return ['MyApp.view_mymodel']

    def get_template_names(self):  # alternate to `template_name`
        if self.request.method == 'POST':
            return ["MyApp/update.html"]
        return ["MyApp/view.html"]
类组合视图(PermissionRequiredMixin、DetailView、UpdateView):
model=MyModel
字段=[“名称”、“类型”、“说明”]
def get_required_权限(self,request=None):#替换为'permission_required'`
如果self.request.method==“POST”:
return['MyApp.change\u mymodel']
return['MyApp.view\u mymodel']
def get_template_name(self):#替换为'template_name'`
如果self.request.method==“POST”:
return[“MyApp/update.html”]

return[“MyApp/view.html”]
现在获取“CombinedView缺少queryset”错误。我也没有遵循请求。method==“POST”行。这些不一定是POST请求,我只想将它们放到“更改”视图中,如果它们具有“更改”权限,这仍然可能是一个GET请求,尽管我可能缺少一些内容。@user3246693更新了应答!错过了模型场。这解决了queryset问题,但检查POST仍在进行中。不过,你确实给我指出了正确的方向,我现在已经开始工作了,将更新原始帖子以包含最终解决方案。非常感谢。我想你可以建议对我的帖子进行编辑,不过今天你可以做些别的!编辑建议
get_required_permissions()
方法正在使用“引擎盖下”检查权限。因此,您不必在if…elase子句中执行相同的操作。我从OP中了解到的是,您需要根据请求方法控制详细信息和更新视图行为(因为在DetailView中使用HTTP GET,在UpdateView中使用HTTP POST)。因此,您的解决方案可能会导致您预期的行为,但我不认为它不会以Django方式解决OP需求。我很好奇这里的“Django方式”是什么。如果我们都浏览到somesite.com/something,而我有更改权限,而你没有,那么我应该看到基于updateView类的视图,而你应该看到listView视图。我发布的解决方案很有效,但我很好奇为什么它不被认为是django方式?