在基于类的表单之间传递数据

时间:2013-02-12 01:54:24

标签: python django django-forms django-views

我对Django和基于类的表单相当新,我很难理解这些表单之间是如何相互作用的。在django project example之后,我试图建立一个“搜索表单”,它将位于我项目的所有页面上:

# 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新手特别是基于类的视图):

  • 如何将数据(“thequery”)传递给success_url?即我希望success_url能够访问“thequery”,这样我就可以在我的模板标签上使用{{thequery}}之类的内容。
  • 在提交表单(name =“home”)后,我在我的firebug上看到表单中的POST数据,但我能够看到“myquery”而不是“thequery”。如何使用get_context_data()来添加/发布“thequery”变量?
  • 最后,我想知道是否有可能根据“thequery”字符串构建success_url,例如success_url ='/ searchres /?q ='+ thequery

提前感谢您 - 我希望了解更多。

1 个答案:

答案 0 :(得分: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']即可访问)。
  2. 您希望尝试避免将数据传递给模板进行处理。在视图中执行尽可能多的处理,然后渲染模板。但是,如果要将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'>更改为,然后使用request.GET访问django中的数据。 (您需要从我上面描述的视图中更改代码,以包含新的检查,以查看您是在处理表单提交还是只是呈现空白表单)

    3. 仔细阅读viewsformsurl dispatcher上的文档。