7

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

class BaseContent(models.Model):
    ...

class XContent(BaseContent):
    ...

class YContent(BaseContent):
    ...

为了保持干燥,我想定义一个 CreateView 类来处理从 BaseContent 继承的所有类。

该视图的 url 模式是:

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来自 url 模式的参数。

长话短说,如何使 CreateView 使用基于从 url 传递的参数的动态表单?

谢谢。

4

2 回答 2

1

您可以model从 your 中设置属性urls.py,具体取决于被调用的 url:

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')

我承认这并不完美,因为您会重复自己一点,但是因此您的优势是可以为同一视图使用不同的名称,具体取决于模型!除此之外,您还可以通过覆盖做类似的事情form_class......

于 2011-06-27T19:34:02.297 回答
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)
    ...
    ...
于 2015-12-10T13:35:54.870 回答