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

时间:2022-11-06 10:03:53

I am fairly new to Django and class based forms, and I am having trouble understanding how these interact with each other. Following from the django project example, I have tried to build a "search form", which would sit on all pages of my project:

我对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"),
)

The plan is the start off with a simple form for user to enter the search query, and also show the input form on the results page. I have the following questions here (sorry - I am a Django newbie esp. to Class Based Views):

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

  • How does one pass data ("thequery") to the success_url? i.e I would like success_url to have access to "thequery" so that I can use something like {{thequery}} on my template tags.
  • 如何将数据(“thequery”)传递给success_url?即我希望success_url能够访问“thequery”,这样我就可以在我的模板标签上使用{{thequery}}之类的东西。

  • Upon submitting the form(name="home"), I see POST data from the form on my firebug, but I am able to see just "myquery" rather than "thequery". How does one use get_context_data() here to add/post "thequery" variable aswell?
  • 在提交表单(name =“home”)后,我在我的firebug上看到表单中的POST数据,但我能够看到“myquery”而不是“thequery”。如何使用get_context_data()来添加/发布“thequery”变量?

  • Finally, I was wondering if it would be possible to construct the success_url based on "thequery" string i.e something like success_url = '/searchres/?q=' + thequery
  • 最后,我想知道是否有可能根据“thequery”字符串构造success_url,即success_url ='/ searchres /?q ='+ thequery

Thank you in advance - I am hoping to learn more.

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

1 个解决方案

#1


1  

I would suggest using function based views for this. If you choose to subclass a generic view you will need to dig through a lot of documentation and possibly source code, to find the right methods to override. (If you're really keen then look at the ListView class along with the get_queryset(), get() and post() methods)

我建议使用基于函数的视图。如果您选择子类通用视图,则需要深入研究大量文档和可能的源代码,以找到正确的方法来覆盖。 (如果你真的很热衷,那么请查看ListView类以及get_queryset(),get()和post()方法)

A single django view will normally handle both rendering the empty form AND processing the submitted form.

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

So the search page (both the form and the results), live at http://your-site.com/search. Your url conf is -

所以搜索页面(包括表单和结果)都在http://your-site.com/search上。你的网址是 -

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

And your view looks something like this -

你的观点看起来像这样 -

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})

(Note I've assumed your form method is post rather than get - I know this isn't great http but it's a common pattern with django)

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

To respond to your questions -

回答你的问题 -

  1. Don't use your own method for cleaning data. Add a clean_myquery method to your form and access it with form.fields['myquery'].clean() (or if you've called is_valid() on your form, it's accessible with just form.cleaned_data['myquery']).
  2. 不要使用自己的方法来清理数据。在表单中添加一个clean_myquery方法并使用form.fields ['myquery']。clean()访问它(或者如果你在表单上调用了is_valid(),只需使用form.cleaned_data ['myquery']访问它。

You want to try and avoid passing data for processing to the template. Do as much processing as you can in the view, then render the template. However if you want to pass myquery as a string for the template to render, then add it in to the context dictionary (the second non-key-word argument) in render_to_response -

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

return render_to_response('search.html', {'object_list': object_list, 'myquery': my query})
  1. The post data is constructed from the form fields. You don't have a form field thequery. The view is processing the POST data - it's not creating it that's done by the html (which in turn is constructed by the Form class). Your variable thequery is declared in the view.

    帖子数据是从表单字段构造的。您没有表单字段thequery。视图正在处理POST数据 - 它不会创建由html完成的(后者又由Form类构造)。您的变量thequery在视图中声明。

  2. Django's URL dispatcher ignores query strings in the URL so http://your_site.com/ssearch will be processed by the same view as http://your_site.com/search?myquery=findstuff. Simply change the html in the template from <form method='post'> to and access the data in django with request.GET. (You'll need to change the code from the view I described above to include a new check to see whether you're dealing with a form submission or just rendering a blank form)

    Django的URL调度程序忽略URL中的查询字符串,因此http://your_site.com/ssearch将通过与http://your_site.com/search?myquery=findstuff相同的视图进行处理。只需将模板中的html从

    更改为,然后使用request.GET访问django中的数据。 (您需要从我上面描述的视图中更改代码,以包含新的检查,以查看您是在处理表单提交还是仅呈现空白表单)

Have a good read of the docs on views, forms and the url dispatcher.

仔细阅读有关视图,表单和URL调度程序的文档。

#1


1  

I would suggest using function based views for this. If you choose to subclass a generic view you will need to dig through a lot of documentation and possibly source code, to find the right methods to override. (If you're really keen then look at the ListView class along with the get_queryset(), get() and post() methods)

我建议使用基于函数的视图。如果您选择子类通用视图,则需要深入研究大量文档和可能的源代码,以找到正确的方法来覆盖。 (如果你真的很热衷,那么请查看ListView类以及get_queryset(),get()和post()方法)

A single django view will normally handle both rendering the empty form AND processing the submitted form.

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

So the search page (both the form and the results), live at http://your-site.com/search. Your url conf is -

所以搜索页面(包括表单和结果)都在http://your-site.com/search上。你的网址是 -

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

And your view looks something like this -

你的观点看起来像这样 -

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})

(Note I've assumed your form method is post rather than get - I know this isn't great http but it's a common pattern with django)

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

To respond to your questions -

回答你的问题 -

  1. Don't use your own method for cleaning data. Add a clean_myquery method to your form and access it with form.fields['myquery'].clean() (or if you've called is_valid() on your form, it's accessible with just form.cleaned_data['myquery']).
  2. 不要使用自己的方法来清理数据。在表单中添加一个clean_myquery方法并使用form.fields ['myquery']。clean()访问它(或者如果你在表单上调用了is_valid(),只需使用form.cleaned_data ['myquery']访问它。

You want to try and avoid passing data for processing to the template. Do as much processing as you can in the view, then render the template. However if you want to pass myquery as a string for the template to render, then add it in to the context dictionary (the second non-key-word argument) in render_to_response -

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

return render_to_response('search.html', {'object_list': object_list, 'myquery': my query})
  1. The post data is constructed from the form fields. You don't have a form field thequery. The view is processing the POST data - it's not creating it that's done by the html (which in turn is constructed by the Form class). Your variable thequery is declared in the view.

    帖子数据是从表单字段构造的。您没有表单字段thequery。视图正在处理POST数据 - 它不会创建由html完成的(后者又由Form类构造)。您的变量thequery在视图中声明。

  2. Django's URL dispatcher ignores query strings in the URL so http://your_site.com/ssearch will be processed by the same view as http://your_site.com/search?myquery=findstuff. Simply change the html in the template from <form method='post'> to and access the data in django with request.GET. (You'll need to change the code from the view I described above to include a new check to see whether you're dealing with a form submission or just rendering a blank form)

    Django的URL调度程序忽略URL中的查询字符串,因此http://your_site.com/ssearch将通过与http://your_site.com/search?myquery=findstuff相同的视图进行处理。只需将模板中的html从

    更改为,然后使用request.GET访问django中的数据。 (您需要从我上面描述的视图中更改代码,以包含新的检查,以查看您是在处理表单提交还是仅呈现空白表单)

Have a good read of the docs on views, forms and the url dispatcher.

仔细阅读有关视图,表单和URL调度程序的文档。