Django-смешивание ListView и CreateView
Я хочу создать одну страницу с формой, и каждый раз, когда я отправить форму, он добавляет элемент в список ниже форма.
Я могу заставить его работать через 2 страницы:
- одна страница с помощью mixin CreateViewдля добавления элементов
- одна страница ListViewиметь список.
но я пытаюсь иметь форму и список на одной странице. Поэтому я попытался создать класс с миксин:
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 FilesPython_2.7libsite-packagesdjangocorehandlersbase.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "C:Program FilesPython_2.7libsite-packagesdjangoviewsgenericbase.py" in view
  47.             return self.dispatch(request, *args, **kwargs)
File "C:Program FilesPython_2.7libsite-packagesdjangoviewsgenericbase.py" in dispatch
  68.         return handler(request, *args, **kwargs)
File "C:Program FilesPython_2.7libsite-packagesdjangoviewsgenericlist.py" in get
  122.         return self.render_to_response(context)
File "C:Program FilesPython_2.7libsite-packagesdjangoviewsgenericbase.py" in render_to_response
  94.             template = self.get_template_names(),
File "C:Program FilesPython_2.7libsite-packagesdjangoviewsgenericlist.py" in get_template_names
  134.             names = super(MultipleObjectTemplateResponseMixin, self).get_template_names()
File "C:Program FilesPython_2.7libsite-packagesdjangoviewsgenericdetail.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'
Я понятия не имею, как это отладить. С чего начать?
4 ответов
Я использую много представлений, которые включают форму и список объектов. Вместо того, чтобы пытаться смешивать вещи, я просто добавляю queryset в контекстные данные, как показано ниже.
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)
Не смешивать список и обновлять представления.
Вместо этого создайте два отдельных представления для этих задач:
посмотреть список отображает список и веб-форму с action URL, указывающий на создать вид.
создать вид принимает данные POST и
- отображает форму с сообщением об ошибке в случае сбоя;
- редирект на посмотреть список в случае успеха.
также я пытался использовать представления на основе классов и обнаружил, что они слишком сложны.
Я думаю, что гораздо проще использовать представления функций старого стиля.
Я нашел ответ, есть 2 проблемы:
- ListView и CreateView-это" высокий уровень "mixin, который агрегирует" ниже уровень" миксины. Но эти миксины нижнего уровня несовместимы друг с другом.
- класс представления вызывает непосредственно render_to_response (), но в моем сценарии есть 2 класса представления, и render_to_response () должен вызываться только один раз в конце.
я смог "решить" эту проблему, используя следующие шаги:
вместо вызова ListView и CreateView я использовал миксины более низкого уровня. Более того, я вызвал явно 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))
это не чисто, но это работает!
Я создал свой собственный класс для решения этой проблемы. Я не знаю, лучше это или хуже, но это тоже работает. Я попытался использовать общие миксины и протестировал эту работу проверки и разбиения на страницы.
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.
