我想创建一个带有表单的页面,每次提交表单时,它都会在表单下方的列表中添加一个项目。
我可以使用2页进行操作:
CreateView
添加项目的一页ListView
以获得该列表。但我正在尝试将表单和列表放在同一页面上。所以我尝试用mixin创建一个类:
class FormAndListView(ListView, CreateView):
pass
然后我用过这个课:
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',)),
但是当我尝试加载页面时,我收到错误: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'
我不知道如何调试它。从哪里开始?
答案 0 :(得分:29)
我使用了很多涉及表单和对象列表的视图。我只是将查询集添加到上下文数据中,而不是尝试混合。
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)
答案 1 :(得分:11)
不要混合列表和更新视图 相反,为这些任务创建两个单独的视图:
列表视图会显示列表和网页表单,其中action
网址指向创建视图。
创建视图接受POST数据和
此外,我尝试使用基于类的视图,发现它们太复杂了 我认为使用旧式函数视图要容易得多。
答案 2 :(得分:8)
我找到了答案,有2个问题:
我可以使用以下步骤“解决”此问题:
我没有调用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))
它不干净但它有效!
答案 3 :(得分:4)
我已经自己上课来解决这个问题。我不知道它是好还是坏,但它也有效。我试图使用通用mixins并测试了验证和分页工作。
class ListAppendView(MultipleObjectMixin,
MultipleObjectTemplateResponseMixin,
ModelFormMixin,
ProcessFormView):
""" A View that displays a list of objects and a form to create a new object.
The View processes this form. """
template_name_suffix = '_append'
allow_empty = True
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
allow_empty = self.get_allow_empty()
if not allow_empty and len(self.object_list) == 0:
raise Http404(_(u"Empty list and '%(class_name)s.allow_empty' is False.")
% {'class_name': self.__class__.__name__})
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
context = self.get_context_data(object_list=self.object_list, form=form)
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
self.object = None
return super(ListAppendView, self).post(request, *args, **kwargs)
def form_invalid(self, form):
self.object_list = self.get_queryset()
return self.render_to_response(self.get_context_data(object_list=self.object_list, form=form))
如果您尝试并发现任何错误,请在此处或GitHub告诉我。
答案 4 :(得分:0)
我遇到了这个问题并使用以下代码解决了它,@jondykeman 的答案没有用于基类的分页和其他实用程序。提出的其他方法比以下方法稍微复杂一些:
class ObjectCreateView(LoginRequiredMixin, MultipleObjectMixin, View):
queryset = Wallet.objects.all()
def get(self, request):
self.object_list = super(ObjectCreateView, self).get_queryset().filter(user=request.user)
allow_empty = super(ObjectCreateView, self).get_allow_empty()
if not allow_empty:
if super(ObjectCreateView, self).get_paginate_by(self.object_list) is not None and hasattr(self.object_list, 'exists'):
is_empty = not self.object_list.exists()
else:
is_empty = not self.object_list
if is_empty:
raise Http404()
context = super(ObjectCreateView, self).get_context_data()
form = CreateObjectForm()
context['form'] = form
return render(request, 'objects/object-list.html', context=context)
def post(self, request):
form = CreateWalletForm(request.POST)
if form.is_valid():
Object.objects.create(name=form.cleaned_data['name'], user=request.user)
messages.success(request, 'Object is created')
else:
messages.error(request, utility.get_form_errors_as_string(form))
return redirect('objects:create')