37

詳細またはリストビューはそれほど複雑ではないため、クラスベースのビューを学習しようとしています。

検索フォームがあり、クエリを送信して結果を表示するかどうかを確認したいだけです。

関数コードは次のとおりです(私のものではなく、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' オブジェクトは呼び出し可能ではありません」というメッセージが表示されます

結構です、私は今日このようなものから始めました。

では、取得 (および必要に応じて投稿) 要求を管理できるクラスベースのビューを作成するにはどうすればよいでしょうか?

別の例があります:

@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

これは、同じ質問を持つ人に任せます:)

4

2 に答える 2

32

FormViewクラスのデフォルトの動作は、リクエストに対してバインドされていないフォームを表示し、 (または) リクエストに対してGETフォームをバインドすることです。バインドされたフォームが有効な場合は、メソッドが呼び出され、(属性またはメソッドによって定義された) 成功 URL にリダイレクトされます。POSTPUTform_validsuccess_urlget_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、結果をページ分割したくない限り、本当の利点はないと思います。

于 2012-01-18T00:50:07.457 に答える
14

ここでの回答 ( 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)

これは私にとって完璧に機能しました。(この質問と同じ問題)

上記のように、これは私の解決策ではありません。誰かにクレジットを与えたい場合は、リンクの回答に移動して、この人にクレジットを与えてください! ( FormView form_valid メソッドでコンテキスト データを更新していますか? )

于 2015-01-03T21:29:51.350 に答える