Django-将模型名称作为参数传递给通用视图

Rob*_*b L 4 django django-generic-views

假设我有一些继承自基类Animal的模型。我可以使用通用视图,并将Cat / 12路由到详细视图,将Dod / 10路由到具有不同上下文的同一详细视图。但是我想从URL中获取Model名称,这样就不必定义路由。

我有这样的事情:

url(r'^cat/(?P<slug>[-\w]+)/$',
    DetailView.as_view(
        queryset=Cat.objects.filter(),
        model=Cat,
        context_object_name='animal',
        template_name='animal/detail.html'),
    name='detail'),
url(r'^dog/(?P<slug>[-\w]+)/$',
    DetailView.as_view(
        queryset=Dog.objects.filter(),
        model=Dog,
        context_object_name='animal',
        template_name='animal/detail.html'),
    name='detail'),
...
Run Code Online (Sandbox Code Playgroud)

显然,这是太多重复的代码。我宁愿做这样的事情:

url(r'^?P<my_animal>\w+/(?P<slug>[-\w]+)/$',
    DetailView.as_view(
        queryset=my_animal.objects.filter(),
        model=my_animal,
        context_object_name='animal',
        template_name='animal/detail.html'),
    name='detail'),
...
Run Code Online (Sandbox Code Playgroud)

我可以这样做吗?

编辑

在达尔文的帮助下,这就是我最终得到的结果。它避免了if / else来获得Model名称:

class AnimalDetailView(DetailView):
    context_object_name='animal'
    template_name='animals/detail.html'

    def dispatch(self, request, *args, **kwargs):
        my_animal = kwargs.get('my_animal', None)
        self.model = get_model('animals',my_animal.capitalize())
        try:
            ret = super(AnimalDetailView, self).dispatch(request, *args, **kwargs)
        except AttributeError:
            raise Http404
        return ret

    def get_queryset(self):
        return self.model.objects.filter()
Run Code Online (Sandbox Code Playgroud)

下次我对继承有疑问时,我将咨询达尔文!大声笑

Dar*_*win 5

您可以从DetailView继承并重写dispatch方法,以使用以下内容构建自己的规则:

class AnimalDetailView(DetailView):
    context_object_name='animal'
    template_name='animal/detail.html'

    def dispatch(self, request, *args, **kwargs):
        my_animal = kwargs.get('my_animal', None)
        if my_animal == 'dog':
            self.model = Dog
        elif my_animal == 'cat':
            self.model = Cat

        return super(AnimalDetailView, self).dispatch(request, *args, **kwargs)

    def get_queryset(self):
        return self.model.objects.filter()
Run Code Online (Sandbox Code Playgroud)

并使用这样的urlpattern:

url(r'^?P<my_animal>\w+/(?P<slug>[-\w]+)/$', AnimalDetailView.as_view())
Run Code Online (Sandbox Code Playgroud)

编辑:上一次我犯了一个错误,因为我们无法实例化视图类,仅使用'as_view()'方法即可。尝试新方法,我认为这会有所帮助。