1

我对 Django 和基于类的表单相当陌生,我无法理解它们如何相互交互。在django 项目示例之后,我尝试构建一个“搜索表单”,它将位于我项目的所有页面上:

# forms.py
from django import forms

class SearchForm(forms.Form):
    myquery = forms.CharField(max_length=255,label="", help_text="sq")

    def __unicode__(self):
        return self.myquery

# views.py
from searchapp.forms import SearchForm
from django.views.generic.edit import FormView
from django.views.generic import TemplateView

class SearchView(FormView):
    template_name = 'index.html'
    form_class = SearchForm
    success_url = '/searchres/'

    def form_valid(self, form):
        thequery=form.cleaned_data.get('myquery')
        return super(SearchView, self).form_valid(form)

    class Meta:
        abstract = True

class SearchResView(SearchView):
    template_name = 'searchres.html'


#urls.py
from django.conf.urls import patterns, include, url
from django.conf import settings
from deals.views import IndexView
from searchapp.views import SearchView, SearchResView

urlpatterns = patterns('',
    url(r'^index/', SearchView.as_view(),name="home"),
    url(r'^searchres/', SearchResView.as_view(),name="searchresx"),
)

该计划是从一个简单的表单开始,让用户输入搜索查询,并在结果页面上显示输入表单。我在这里有以下问题(抱歉 - 我是 Django 新手,尤其是基于类的视图):

  • 如何将数据(“查询”)传递给success_url?即我希望success_url 能够访问“thequery”,这样我就可以在我的模板标签上使用类似{{thequery}} 的东西。
  • 提交表单(name="home")后,我在我的萤火虫上看到了表单中的 POST 数据,但我只能看到“myquery”而不是“thequery”。如何在这里使用 get_context_data() 来添加/发布“查询”变量?
  • 最后,我想知道是否可以基于“thequery”字符串构造success_url,即类似success_url = '/searchres/?q=' + thequery

在此先感谢您-我希望了解更多信息。

4

1 回答 1

1

我建议为此使用基于函数的视图。如果您选择子类化通用视图,您将需要挖掘大量文档和可能的源代码,以找到正确的方法来覆盖。(如果你真的很感兴趣,那么看看这个ListView类以及get_queryset(),get()post()方法)

单个 django 视图通常会处理呈现空表单和处理提交的表单。

因此,搜索页面(包括表单和结果)位于http://your-site.com/search。您的网址配置是 -

urlpatterns = patterns('',
    #...
    (r'^search/$', 'searchapp.views.search'),
)

你的观点看起来像这样 -

def search(request):
    if request.method == 'POST':
        form = SearchForm(request.POST)
        if form.is_valid():
            my_query = form.cleaned_data['myquery']
            object_list = YourModel.objects.filter(# some operation involving my_query)
            return render_to_response('search_results.html', {'object_list': object_list})
     else:
        form = SearchForm()
     render_to_response('search_form.html', {'form': form})

(请注意,我假设您的表单方法是 post 而不是 get - 我知道这不是很好的 http,但它是 django 的常见模式)

回答您的问题 -

  1. 不要使用自己的方法来清理数据。将clean_myquery方法添加到您的表单并使用form.fields['myquery'].clean()(或者,如果您已is_valid()在表单上调用,则可以使用 访问它form.cleaned_data['myquery'])。

您想尝试避免将要处理的数据传递给模板。在视图中进行尽可能多的处理,然后渲染模板。但是,如果您想将 myquery 作为字符串传递给模板以呈现,则将其添加到上下文字典(第二个非关键字参数)中render_to_response-

return render_to_response('search.html', {'object_list': object_list, 'myquery': my query})
  1. 发布数据是从表单字段构造的。您没有表单域thequery。视图正在处理 POST 数据 - 它不是由 html 完成的创建它(它又由 Form 类构造)。您的变量thequery在视图中声明。

  2. Django 的 URL 调度程序忽略 URL 中的查询字符串,因此http://your_site.com/ssearch将由与http://your_site.com/search?myquery=findstuff相同的视图处理。只需将模板中的 html 从<form method='post'>to 更改为并使用request.GET. (您需要从我上面描述的视图中更改代码,以包含一个新检查,以查看您是在处理表单提交还是只是呈现空白表单)

好好阅读有关视图表单url 调度程序的文档。

于 2013-02-12T15:37:55.147 回答