Django - 混合ListView和CreateView

Nic*_*ico 13 django listview mixins

我想创建一个带有表单的页面,每次我提交表单时,它都会在表单下方的列表中添加一个项目.

我可以使用2页来使其工作:

  • 一页使用mixin CreateView添加项目
  • 一页ListView有列表.

但我正在尝试将表单和列表放在同一页面上.所以我尝试用mixin创建一个类:

class FormAndListView(ListView, CreateView):
    pass
Run Code Online (Sandbox Code Playgroud)

然后我用过这个课:

FormAndListView.as_view(
    queryset=PdfFile.objects.order_by('id'),
    context_object_name='all_PDF',
    success_url = 'listview',
    form_class = UploadFileForm,
    template_name='textfrompdf/index.html',)),
Run Code Online (Sandbox Code Playgroud)

但是当我尝试加载页面时,我收到错误: Exception Value: 'FormAndListView' object has no attribute 'object'

Traceback:
File "C:\Program Files\Python_2.7\lib\site-packages\django\core\handlers\base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "C:\Program Files\Python_2.7\lib\site-packages\django\views\generic\base.py" in view
  47.             return self.dispatch(request, *args, **kwargs)
File "C:\Program Files\Python_2.7\lib\site-packages\django\views\generic\base.py" in dispatch
  68.         return handler(request, *args, **kwargs)
File "C:\Program Files\Python_2.7\lib\site-packages\django\views\generic\list.py" in get
  122.         return self.render_to_response(context)
File "C:\Program Files\Python_2.7\lib\site-packages\django\views\generic\base.py" in render_to_response
  94.             template = self.get_template_names(),
File "C:\Program Files\Python_2.7\lib\site-packages\django\views\generic\list.py" in get_template_names
  134.             names = super(MultipleObjectTemplateResponseMixin, self).get_template_names()
File "C:\Program Files\Python_2.7\lib\site-packages\django\views\generic\detail.py" in get_template_names
  122.         if self.object and self.template_name_field:

Exception Type: AttributeError at /PDF/
Exception Value: 'FormAndListView' object has no attribute 'object'
Run Code Online (Sandbox Code Playgroud)

我不知道如何调试它.从哪儿开始?

jon*_*man 31

我使用了很多涉及表单和对象列表的视图.我只是将查询集添加到上下文数据中,而不是尝试混合.

class UploadFileView(CreateView):
    form_class = UploadFileForm
    success_url = 'listview'
    template_name = 'textfrompdf/index.html'

    def get_context_data(self, **kwargs):
        kwargs['object_list'] = PdfFile.objects.order_by('id')
        return super(UploadFileView, self).get_context_data(**kwargs)
Run Code Online (Sandbox Code Playgroud)

  • 这可能非常优雅,但有助于获得更多解释. (6认同)

Gre*_*hov 10

不要混合列表和更新视图.
而是为这些任务创建两个单独的视图:

列表视图显示列表和Web表单,其actionURL指向创建视图.
创建视图接受POST数据和

  • 在出现故障时显示带有错误消息的表单;
  • 如果成功,重定向到列表视图.

此外,我尝试使用基于类的视图,发现它们太复杂了.
我认为使用旧式函数视图要容易得多.


Nic*_*ico 8

我找到了答案,有2个问题:

  • ListView和CreateView是"高级"混合,聚合"低级"混合.但是这些较低级别的mixin不兼容.
  • View类直接调用render_to_response(),但在我的场景中,有2个视图类,render_to_response()只应在结尾调用一次.

我能够使用以下步骤"解决"此问题:

我没有调用ListView和CreateView,而是使用了较低级别的mixins.此外,我明确调用了BaseCreateView和BaseListView,我从中"提取"了表单和object_list

class FormAndListView(BaseCreateView, BaseListView, TemplateResponseMixin):
    def get(self, request, *args, **kwargs):
        formView = BaseCreateView.get(self, request, *args, **kwargs)
        listView = BaseListView.get(self, request, *args, **kwargs)
        formData = formView.context_data['form']
        listData = listView.context_data['object_list']
        return render_to_response('textfrompdf/index.html', {'form' : formData, 'all_PDF' : listData},
                           context_instance=RequestContext(request))
Run Code Online (Sandbox Code Playgroud)

它不干净,但它的工作原理!

  • 这种观点太多了,很难保持这种观点.用户`jondykeman`有一个更安全,更优雅的解决方案来解决这个问题. (6认同)