验证Django表格GET请求

时间:2015-09-11 00:42:42

标签: django forms validation

我试图通过GET请求验证传递给Django表单的数据。典型的表单用法是验证request.POST,但我想验证搜索表单的数据,这是GET请求。我有以下代码,它使用FormMixinListView,它可以正常工作,但我返回一个完整或空的查询集,这两个查询集都不会使表单验证失效。

class PostSearchView(FormMixin, ListView):
    template_name = 'blog/post_search.html'
    paginate_by = getattr(settings, 'PAGINATE_BY', 10)
    form_class = SearchForm
    success_url = reverse_lazy('post_search')

    def get(self, request, *args, **kwargs):
        if 'q' in self.request.GET:
            form_class = self.get_form_class()
            form = form_class(self.request.GET)
            if form.is_valid():
                q = form.cleaned_data['q']
                post_list = Post.objects.is_published().filter(Q(title__icontains=q) | Q(body__icontains=q))
            else:
                post_list = Post.objects.none()
        else:
            form = self.get_form()
            post_list = Post.objects.none()
        self.object_list = post_list
        context = self.get_context_data(post_list=post_list, form=form)
        return self.render_to_response(context)

一个空字符串的查询(只是点击"搜索")应返回带有验证错误的同一视图。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我的代码是正确的。我想也许这是一个缓存问题。很抱歉浪费每个人的时间。

然而,应该做出一些改进:

  • success_url是不必要的,因为不应该重定向到任何内容;它只是使用其他查询参数重新呈现相同的视图
  • post_list传递给上下文是多余的,有点害;通过将其存储在self.object_list中,post_listobject_list被识别为视图的查询集,并自动分页并添加到上下文中。通过将post_list放回上下文,分页就会被吹走。
  • 为了确保分页在查询字符串中起作用并且只是为了一般可用性,应该将查询(form.cleaned_data['q']或强制为None)显式传递给上下文。
  • 如果搜索表单将通过上下文处理器在多个页面上,则可能值得将form重命名为post_search_form或其他内容。

改进后的观点:

class PostSearchView(FormMixin, ListView):
    template_name = 'blog/post_search.html'
    paginate_by = getattr(settings, 'PAGINATE_BY', 10)
    form_class = SearchForm

    def get(self, request, *args, **kwargs):
        if 'q' in self.request.GET:
            form_class = self.get_form_class()
            form = form_class(self.request.GET)
            if form.is_valid():
                q = form.cleaned_data['q']
                post_list = Post.objects.is_published().filter(Q(title__icontains=q) | Q(body__icontains=q))
            else:
                q = None
                post_list = Post.objects.none()
        else:
            q = None
            form = self.get_form()
            post_list = Post.objects.none()
        self.object_list = post_list
        context = self.get_context_data(form=form, query=q)
        return self.render_to_response(context)

分页模板包括:

{% if page_obj.has_other_pages %}
<nav>
    <ul class="pager">
        {% if page_obj.has_previous %}
        <li class="previous"><a href="?{% if query %}q={{ query }}&amp;{% endif %}page={{ page_obj.previous_page_number }}">&larr; Newer</a></li>
        {% endif %}
        {% if page_obj.has_next %}
        <li class="next"><a href="?{% if query %}q={{ query }}&amp;{% endif %}page={{ page_obj.next_page_number }}">Older &rarr;</a></li>
        {% endif %}
    </ul>
</nav>
{% endif %}