2012-06-06 29 views
5

ユーザーがログインしているかどうかに応じてReCaptchaフィールドを持つか持っていないFormクラスを作成する必要があります。フォーム内の条件フィールド

これはコメントフォームなので、フォーム作成/定義でrequestオブジェクトにアクセスすることはできないので、私はそれに頼ることはできません。 POST要求解決のために

は簡単です:私はこれを持っている:

class ReCaptchaCommentForm(CommentForm): 
    def __init__(self, data=None, *args, **kwargs): 
     super(ReCaptchaCommentForm, self).__init__(data, *args, **kwargs) 
     if data and 'recaptcha_challenge_field' in data: 
      self.fields['captcha'] = ReCaptchaField() 

が意図したように、フォームの検証が動作するはずこれを行いました。問題は今テンプレート側にあります。私は、テンプレートは次のようにする必要があります

<form action={% comment_form_target %} method="post"> 
{# usual form stuff #} 
{% if not user.is_authenticated %} 
<script type="text/javascript" 
     src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script> 
<div id="recaptcha-div"></div> 
<script type="text/javascript"> 
    Recaptcha.create({{ public_key }}, "recaptcha-div", 
        { theme: 'white', 
        callback: Recaptcha.focus_response_field }); 
</script> 
{% endif %} 
</form> 

しかし、私はすべてのcomments/*/form.htmlテンプレートにそのコードを繰り返す必要がないようにしたいと思います。ウィジェットのrenderメソッドとMedia定義から同等のコードを追加する方法があるはずです。

これを行うにはいい方法はありますか?

+1

問題はウィジェットがリクエストについて何も知らないため、ログインしたユーザーに基づいて条件付きでレンダリングする方法がないことです。しかし、あなたはdjango-floppyformsを見たいかもしれません。テンプレートを使用してウィジェットをレンダリングするので、そのようにすることができます。 –

+0

はい、それは私が持っていたアイデアです。テンプレートを通してウィジェットをレンダリングします。しかし、私は私がこれを行う場合でも、私のテンプレート変数にrequest.userを持てるかどうかはわかりません(widget.renderは、テンプレートのレンダリング、コンテキストが問題です)。 私がしたいと思うのは、後で解析されるテンプレートをレンダリングすることです。 – Lacrymology

+1

だから私はdjango-floppyformsを提案しました。私は完全にはわかりませんが、単純に 'render'にテンプレートを使用させるのではなく、標準インクルードパターンで動作すると思います。他のインクルードされたテンプレートと同じように、テンプレートコンテキストで 'request'にアクセスできるはずです。それを試してみてください。 –

答えて

4

私はあなただけのリクエストからフォーム(単に認証アプリSetPassword形のように)にユーザーを渡すことができるようにあなたは、ビューでフォームをinstatiateことを前提としています

def __init__(self, user, data=None, *args, **kwargs): 
    super(ReCaptchaCommentForm, self).__init__(data, *args, **kwargs) 
    if user.is_authenticated(): 
     self.fields['captcha'] = ReCaptchaField() 
+0

いいえ、コメントシステムはそのようには機能しません(ビューではなく、テンプレートタグであり、リクエストとしてORを渡しません)。説明の一部です! – Lacrymology

0

まあ、django-floppyformsがリクエストにアクセスできないことは残念です。私は最近自分のプロジェクトでdjango-floppyformsを使い始めたので、それがオプションだったことを知ってうれしいです。

私が考えることができる最も良いことは、単にテンプレートの継承に頼ることです。 comments/form.htmlファイルを作成して、それぞれをcomments/*/form.htmlに拡張することができます。 Recaptchaコードをベースform.htmlに入れておいてください。あなたは良いです。

+0

から実行されていますが、それはもっとうまくいっています。特に、a)私はコメントシステム外のフォームに対しても同じことをする必要があります。b)これは些細なものでなければなりません。 – Lacrymology

+0

それはちょっとしたことですね。すべてのフォームが継承する基本テンプレートにスクリプトを追加するだけです。また、コメントシステムの外に必要な場合は、さらに上位のform.htmlテンプレート(メインテンプレートディレクトリのすぐ上にある)を持つことができず、このアプリケーションとそれを必要とする他のすべてのアプリケーションが継承しているということは何もありません。 –

3

使用crispy-forms! ビューレイアウトのコンテキストに基づいてフィールドを除外/含めることができるフォームレイアウトにhtml要素を含めることができます。それ以外にも非常に便利な機能です。私は条件付きフィールドについてやっている何を

Here's the relevant doc section.

+0

ああ、私実際にはクリスピー・フォームを使用していますが、まだテンプレートを使用したメソッドを使用しているので、まだ使用していません。 – Lacrymology

0

は、余分な条件付きのフィールドを持つベース(Formから継承)クラスと他のサブクラスを持っています。

私の見解では、条件に応じて、必要なサブクラス化されたフォームを選択します。重複したコードが含まれていることはわかっていますが、他のアプローチよりも簡単です。