クラスビューを学習しようとしていますが、詳細ビューまたはリストビューはそれほど複雑ではありません。
検索フォームがあり、クエリを送信して結果を表示するかどうかを確認したいだけです。
以下に関数コードを示します(私のものではなく、Django book)からのものです):
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()
これは最初のものと同じ方法で「変換」されるでしょうか?または、異なるビューを拡張しますか?
とても混乱しています。最初がProcessFormViewで、2番目が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
私はこれを同じ質問のある人に任せます:)
FormView
クラスのデフォルトの動作は、GET
リクエストの非バインドフォームを表示し、POST
(またはPUT
)リクエスト。バインドされたフォームが有効な場合、form_valid
メソッドが呼び出され、成功URL(success_url
属性またはget_success_url
メソッドで定義される)にリダイレクトされます。
これは例と非常によく一致します。スーパークラスメソッドを呼び出して成功URLにリダイレクトする前に、form_valid
メソッドをオーバーライドして新しいUser
を作成する必要があります。
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
に入れてみます。それが機能するようになったら、GETデータを解析して独自のメソッドにブックマークを返すコードをファクタリングできます。 ListView
の拡張を見ることができますが、結果をページ分割したい場合を除いて、本当の利点はないと思います。
注、ここでの回答( FormView form_validメソッドでコンテキストデータを更新しますか? )は、この問題を次のように解決しました。
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)
これは私にとって完璧に機能しました。 (この質問と同じ問題)
上記のように、これは私の解決策ではありません。誰かにクレジットを与えたい場合は、リンクの答えに行き、この人にクレジットを与えてください! ( FormView form_validメソッドでコンテキストデータを更新しますか? )