Django:基于参数类的视图

时间:2011-06-25 14:29:46

标签: django django-views django-class-based-views

我正在尝试使用通用的CreateView类来处理从同一基类继承的一组模型的表单。

class BaseContent(models.Model):
    ...

class XContent(BaseContent):
    ...

class YContent(BaseContent):
    ...

为了保持DRY,我想定义一个CreateView类,它将处理来自BaseContent的所有继承类。

该视图的网址格式为:

url(r'^content/add/(?P<model_name>\w+)/$', ContentCreateView.as_view(), name='content_add')

这样的事情应该有效:

class ContentCreateView(CreateView):
    template_name = 'content_form.html'

    def get_model(self, request):
        # 'content' is the name of the application; model_name is 'xcontent', 'ycontent', ...
        return ContentType.objects.get_by_natural_key('content', self.model_name)

但我得到了这个例外:

ContentCreateView is missing a queryset. Define ContentCreateView.model, ContentCreateView.queryset, or override ContentCreateView.get_object().

这个建议似乎并不成立,因为我不愿意设置像modelqueryset这样的类属性来保持动态模型表单的生成。覆盖get_object似乎与创建对象无关。

我尝试覆盖get_queryset(),但此方法不接受request参数,也无法访问来自网址格式的self.model_name

长话短说,如何让CreateView根据从网址传递的参数使用动态表单?

感谢。

2 个答案:

答案 0 :(得分:1)

您可以设置model的{​​{1}}属性,具体取决于所调用的网址:

urls.py

我承认它并不完美,因为你有点重复自己,但因此你可以为同一个视图设置不同的名称,具体取决于模型!除此之外,你还可以做一些与覆盖url(r'^content/add/x/$', ContentCreateView.as_view(model=XContent), name='x_content_add'), url(r'^content/add/y/$', ContentCreateView.as_view(model=YContent), name='y_content_add') ...

类似的事情

答案 1 :(得分:1)

这个问题已经有一段时间了,但找到了解决方案。您需要覆盖as_view()(django.views.generic.base)中定义的调度方法,如下所示:

class ContentCreateView(CreateView):    
    def dispatch(self, request, *args, **kwargs):
        for app in ['foo', 'bar']:
            model = models.get_model(app, kwargs['modelname'])
            if model:
                self.model = model
                break

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