【问题标题】:Django: ListView with post() method?Django:使用 post() 方法的 ListView?
【发布时间】:2013-03-25 18:43:02
【问题描述】:

我正在尝试在基于 Django 类的视图中处理两个表单。该站点包含一个名为form(基于GET)的表单,用于缩小ListView 的列表结果和第二个表单status_form(基于POST)。

这两种形式都是必需的,因为 ListView 返回一个项目列表。 Form 让用户限制选择,status_forms 让用户通过模式表单标记不正确的项目(因此它需要在同一个模板中)。

我的问题是ListView 没有post 方法,但是FormView 有。我的类List 继承自两个类,但是当我执行该类时,我收到错误消息:

属性错误:“列表”对象没有属性“status_form”

我应该如何更改我的实现以允许通过post method 处理第二个表单?

class List(PaginationMixin, ListView, FormMixin):
    model = ListModel
    context_object_name = 'list_objects'
    template_name = 'pages/list.html'
    paginate_by = 10 #how may items per page

    def get(self, request, *args, **kwargs):
        self.form = ListSearchForm(self.request.GET or None,)
        return super(List, self).get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.status_form = StatusForm(self.request.POST or None)
        if self.status_form.is_valid():
            ...
        else:
            return super(List, self).post(request, *args, **kwargs)

    def get_queryset(self):
        # define the queryset
        ...
        # when done, pass to object_list
        return object_list

    def get_context_data(self, **kwargs):
        context = super(List, self).get_context_data(**kwargs)
        context.update(**kwargs)
        context['form'] = self.form
        context['status_form'] = self.status_form # Django is complaining that status_form is not existing, result since the post method is not executed
        return context

【问题讨论】:

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


    【解决方案1】:
    # Django is complaining that status_form does not exist,
    # result since the post method is not executed
    context['status_form'] = self.status_form
    

    因为你一开始没有定义self.status_from。 您已经在get_context_data 中定义了它,并且可以从那里访问它。

    您可以在您的 post 方法中从 get_context_data 访问您的对象;

    context = self.get_context_data(**kwargs)
    status_form = context['status_form']
    

    还请考虑您可以直接在post 方法本身中定义您的status_form,而无需从selfget_context_data 获取它。

    重新设计您的视图以将每个表单处理分隔在单独的视图中,然后将它们彼此紧密。

    视图重新设计:

    简而言之,让每个视图做一项工作。您可以创建一个视图仅用于处理您的 status_form 并将其命名为 StatusFormProcessView 然后在您的 List 视图上返回它的 post 方法

    class List(ListView);
        def post(self, request, *args, **kwargs):
            return StatusFormView.as_view()(request) # What ever you need be pass to you form processing view
    

    这只是一个例子,需要更多的工作才能成为现实。

    再举一个例子;在我的网站索引页面上,我有一个搜索表单。当用户POSTGET 搜索表单时,我的IndexView 中不存在搜索处理,而是在单独的视图中处理整个表单内容,如果表单应该在GET 方法上处理,我'将覆盖get() 方法,如果表单应在POST 上处理,我将覆盖post() 方法以将search_form 数据发送到负责处理search_form 的视图。

    评论回复

    status_form = context['status_form']

    不应该吗

    context['status_form'] = status_form
    

    在我创建之后?

    你想从context得到status_form,所以你需要

    status_form = context['status_form']
    

    无论如何,您的表单数据在self.request.POST 上可用

    【讨论】:

    • 您能否解释一下重新设计视图的含义?我对 status_form = context['status_form'] 这一行感到困惑,我创建后不应该是 context['status_form'] = status_form 吗?谢谢你的建议。
    • 当你按照你的建议去做,并传递给return StatusFormView.as_view(request)时,我得到TypeError: as_view() takes 1 positional argument but 2 were given。我不知道如何解决这个问题。
    • 2 分钟后...该行应该是:return StatusFormView.as_view()(request)
    • @PhilGyford 感谢您提出的修复建议。我已根据您的建议更新了答案。
    猜你喜欢
    • 2017-07-16
    • 2019-02-24
    • 1970-01-01
    • 2013-01-12
    • 2019-02-26
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    • 2018-09-25
    相关资源
    最近更新 更多