2012-01-18 48 views
29

我試圖學習基於類的視圖,對於細節或列表視圖並不那麼複雜。如何使用基於類的視圖處理表單(通過get或post)?

我有一個搜索表單,我只是想看看我是否發送一個查詢,以顯示結果。

下面是函數代碼(不是我的,是從一個Django書):

def search_page(request): 
    form = SearchForm() 
    bookmarks = [] 
    show_results = False 
    if 'query' in request.GET: 
     show_results = True 
     query = request.GET['query'].strip() 
     if query: 
      form = SearchForm({'query': query}) 
      bookmarks = Bookmark.objects.filter(title__icontains=query)[:10] 


    show_tags = True 
    show_user = True 

    if request.is_ajax(): 
     return render_to_response("bookmarks/bookmark_list.html", locals(), context_instance=RequestContext(request)) 
    else: 
     return render_to_response("search/search.html", locals(), context_instance=RequestContext(request)) 

忽略了ajax事實(只是爲了使問題更容易了),我該怎麼翻譯這個上課基於視圖?

我快試過這樣的事情:

class SearchPageView(FormView): 
    template_name = 'search/search.html' 

    def get(self, request, *args, **kwargs): 
     form = SearchForm() 
     self.bookmarks = [] 
     self.show_results = False 
     if 'query' in self.request.GET: 
      self.show_results = True 
      query = self.request.GET['query'].strip() 
      if query: 
       form = SearchForm({'query': query}) 
       self.bookmarks = Bookmark.objects.filter(title__icontains=query)[:10] 
     return super(SearchPageView, self).get(request, *args, **kwargs) 

    def get_context_data(self, **kwargs): 
     context = super(SearchPageView, self).get_context_data(**kwargs) 
     context.update({ 
      'show_tags': True, 
      'show_user': True, 
      'show_results': self.show_results, 
      'bookmarks': self.bookmarks 
     }) 
     return context 

不工作,我得到了:「‘NoneType’對象不是可調用的」

很公平,我今天開始這個東西。

那麼,什麼是做可以管理一個get(和太多,如果需要後)請求基於類的意見的方式嗎?

我有另外一個例子:

@render_to('registration/register.html') 
def register_page(request): 
    if request.method == 'POST': 
     form = RegistrationForm(request.POST) 
     if form.is_valid(): 
      user = User.objects.create_user(
       username=form.cleaned_data['username'], 
       password=form.cleaned_data['password1'], 
       email=form.cleaned_data['email'] 
      ) 
      return HttpResponseRedirect('/accounts/register/success/') 
    else: 
     form = RegistrationForm() 
    return locals() 

這會是「轉化」的方式,第一個一樣的嗎?或者他們擴大differents意見?

林混淆了很多。我不知道如果第一個是ProcessFormView和第二個FormView或什麼。

謝謝。

編輯:解決方案我結束了:

class SearchPageView(FormView): 
    template_name = 'search/search.html' 

    def get(self, request, *args, **kwargs): 
     self.bookmarks = [] 
     self.show_results = False 
     form = SearchForm(self.request.GET or None) 
     if form.is_valid(): 
      self.show_results = True 
      self.bookmarks = Bookmark.objects.filter(title__icontains=form.cleaned_data['query'])[:10] 

     return self.render_to_response(self.get_context_data(form=form)) 


    def get_context_data(self, **kwargs): 
     context = super(SearchPageView, self).get_context_data(**kwargs) 
     context.update({ 
      'show_tags': True, 
      'show_user': True, 
      'show_results': self.show_results, 
      'bookmarks': self.bookmarks 
     }) 
     return context 

我離開這個位置的人有同樣的問題:)

+1

複製和粘貼''NoneType'對象不可調用''不是很有用如果您查看回溯行中的行號,您可以看到哪行代碼引發異常,這可能有助於你自己解決問題 – Alasdair 2012-01-18 00:32:31

+0

問題更新了,你是對的,我不得不去睡覺,我認爲我需要指定我的表單類和你是對的, – 2012-01-18 11:29:34

回答

23

FormView類的默認行爲是顯示GET綁定表單請求,並結合形式POST(或PUT)請求。如果被綁定的形式是有效的,那麼form_valid方法被調用,它只是重定向到成功URL(由success_url屬性或get_success_url方法定義。

這個例子匹配得很好。你需要重寫form_valid方法創建新User,父類方法重定向到URL成功之前。

class CreateUser(FormView): 
    template_name = 'registration/register.html' 
    success_url = '/accounts/register/success/' 
    form_class = RegistrationForm 

    def form_valid(self, form): 
     user = User.objects.create_user(
       username=form.cleaned_data['username'], 
       password=form.cleaned_data['password1'], 
       email=form.cleaned_data['email'] 
     ) 
     return super(CreateUser, self).form_valid(form) 

你的第一個例子不匹配的FormView流這麼好,是因爲你不處理的形式與POST數據,當表格有效時你什麼都不做。

我可能會嘗試擴大TemplateView,並且把所有的邏輯get_context_data。 一旦你得到工作,你可以說因子解析獲取數據,然後返回書籤到它自己的方法的代碼。你可以看看擴展ListView,但我不認爲有任何真正的優勢,除非你想分頁結果。

+0

作品像一個魅力這個例子(改變的名字屬性:P)但是我仍然認爲第一個例子需要一個正確的基於類的視圖表示 – 2012-01-18 11:36:36

+1

是的,很好的地方,我修復了屬性名稱 – Alasdair 2012-01-18 11:45:25

+0

你能幫我解決這個問題嗎? ,它是在form_valid方法之後去的,它對我來說是神奇的。 – izdi 2014-04-24 15:19:50

4

注意,這裏的答案(Updating context data in FormView form_valid method?)解決了這個問題是這樣的:

class ContextFormView(FormView): 
    template_name = 'some_template.html' 
    success_url = '...' 
    form_class = ClassOfTheForm 

    def get(self, request, *args, **kwargs): 
     form_class = self.get_form_class() 
     form = self.get_form(form_class) 
     context = self.get_context_data(**kwargs) 
     context['form'] = form 
     return self.render_to_response(context) 

    def post(self, request, *args, **kwargs): 
     form_class = self.get_form_class() 
     form = self.get_form(form_class) 
     if form.is_valid(): 
      return self.form_valid(form, **kwargs) 
     else: 
      return self.form_invalid(form, **kwargs) 


    def form_invalid(self, form, **kwargs): 
     context = self.get_context_data(**kwargs) 
     context['form'] = form 
     # here you can add things like: 
     context[show_results] = False 
     return self.render_to_response(context) 

    def form_valid(self, form, **kwargs): 
     context = self.get_context_data(**kwargs) 
     context['form'] = form 
     # here you can add things like: 
     context[show_results] = True 
     return self.render_to_response(context) 

這爲我工作完美。 (同樣問題在這個問題)

如上所述,這不是我的解決方案,如果你想給某人學分,去鏈接的答案,並給這個人的學分! (Updating context data in FormView form_valid method?

相關問題