【问题标题】:Django - FormView combined with MixinDjango - FormView 结合 Mixin
【发布时间】:2014-07-07 14:28:19
【问题描述】:

我必须指定success_url,否则我会收到错误消息。那么如何指定它,以便停留在同一页面上呢? 此外,关于 SearchView 的其他所有内容是否正确,因为我觉得缺少某些东西。我的上下文应该由formqueryconceptslanguagelanguages 组成。 谢谢

urls.py

url(r'^(?P<langcode>[a-zA-Z-]+)/search/$', SearchView.as_view(), name='search').

views.py

class _LanguageMixin(object):

    def dispatch(self, request, *args, **kwargs):
        self.langcode = kwargs.pop("langcode")
        self.language = get_object_or_404(Language, pk=self.langcode)
        return super(_LanguageMixin, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(_LanguageMixin, self).get_context_data(**kwargs)
        context.update({"language": self.language,
                        "languages": Language.objects.values_list('code',
                                                                  flat=True)})
        return context


class SearchView(_LanguageMixin, FormView):
    template_name = "search.html"
    form_class = SearchForm
    success_url = #......

    query = ''
    concepts = []

    def get_initial(self):
        return {'langcode': self.langcode}

    def get_context_data(self, **kwargs):
        context = super(SearchView, self).get_context_data(**kwargs)

        context.update({"query": self.query, "concepts": self.concepts})
        return context

    def form_valid(self, form):
        self.query = form.cleaned_data['query']
        self.concepts = # here is a long DB query; function(query)

        return super(SearchView, self).form_valid(form)

[编辑] 我这样做了:

def get_success_url(self):
        return reverse('search', kwargs={'langcode': self.langcode})+"?query={}".format(self.query)

表单呈现,但每当我搜索任何内容时,我都会返回空的搜索文本字段。 URL 看起来像这样:http://localhost:8000/en-US/search/?query=asd

【问题讨论】:

    标签: django django-forms mixins django-class-based-views


    【解决方案1】:

    默认情况下,FormView(实际上是ProcessFormView 的任何子类)将在form_valid 中返回HttpResponseRedirect。当您在form_valid 方法中调用super 的方法时,您还返回了HttpResponseRedirect。在此过程中,实际的POST 数据会丢失,尽管您将其作为GET 参数传递,但实际表单中并未使用它。

    要解决此问题,您无需在 form_valid 方法中调用 super,而是在 HttpResponse 对象中返回渲染模板,例如:

    def form_valid(self, form):
        self.query = form.cleaned_data['query']
        self.concepts = # here is a long DB query; function(query)
    
        return self.render_to_response(self.get_context_data(form=form))
    

    【讨论】:

    • 我会在回到电脑前尝试您的解决方案。然而,为什么 POST 数据会丢失?因为我在处理 form_valid 时保存了上下文,并且 super 内部的重定向应该知道这一点。我错了吗?
    • 这是 HTTP 级别的重定向 - 您告诉客户端的浏览器在没有 POST 数据的情况下对成功 url 执行新请求。这是POST 请求的常见做法,因为这些请求通常会更改数据库中的数据并且不应执行两次。通过重定向,用户不会意外地将数据两次发送到服务器。但是,在这种情况下,您使用数据来生成响应,因此您不应该重定向用户。您甚至可能想在您的 dispatch 方法上使用 csrf_exempt 装饰器来允许跨站点请求。
    猜你喜欢
    • 2013-05-31
    • 2019-12-22
    • 2015-04-09
    • 2016-07-30
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    相关资源
    最近更新 更多