12

ユーザが選択された場合に、そのユーザに選択肢のあるアクションを適用するユーザとチェックボックスのリストを含むページを作成します。私は表に記載されているユーザーがいると私は、この表の最後の列は、これらのチェックボックスになりたい私のテンプレートではテンプレート内でdjangoフォームフィールドをレンダリングする方法

#in forms.py 
class UserSelectionForm(forms.Form): 
    """form for selecting users""" 
    def __init__(self, userlist, *args, **kwargs): 
     self.custom_fields = userlist 
     super(forms.Form, self).__init__(*args, **kwargs) 
     for f in userlist: 
      self.fields[str(f.id)] = forms.BooleanField(initial=False)  

    def get_selected(self): 
     """returns selected users""" 
     return filter(lambda u: self.fields[str(u.id)], self.custom_fields) 

: 私はこのようになりますフォームクラスを作成しました。名前に応じてフィールドを1つずつレンダリングする必要があります。 私は必要なフォーム要素のHTMLコードを返すテンプレートタグを作成してみました:

#in templatetags/user_list_tags.py 
from django import template 
register = template.Library() 

#this is django template tag for user selection form 
@register.filter 
def user_select_field(form, userid): 
    """ 
    returns UserSelectionForm field for a user with userid 
    """ 
    key = std(userid) 
    if key not in form.fields.keys(): 
     print 'Key %s not found in dict' % key 
     return None 
     return form.fields[key].widget.render(form, key) 

は最後に、ここではテンプレートのコードは次のとおりです。

<form action="" method="post"> 
{% csrf_token %} 
<table class="listtable"> 
    <tr> 
    <th>Username</th> 
    <th>Select</th> 
    </tr> 
{% for u in userlist %} 
    <tr> 
    <td>{{u.username}}</td> 
    <td>{{select_form|user_select_field:u.id}}</td> 
    </tr> 
{% endfor %} 
</table> 
<p><input type="submit" value="make actions" /></p> 

しかし、これはにそれらのウィジェットを結合しませんフォームを送信した後、検証は失敗します。エラーメッセージには、すべてのカスタムフィールドが必要であることが示されています。 だからここに私の質問は以下のとおりです。

  1. 別のフォームフィールドをレンダリングするための正しい方法は何ですか?

  2. このようなフォームをチェックボックスで作成する正しい方法は何ですか? (私は多分意味、私の方法はばかげていると私は何をしたい達成するための非常に簡単な方法があります。

+0

多分あなたは少しのjavascriptでこれをやってみるべきです。 – unni

+0

私はこの段階で自分のプロジェクトでjavascriptを使いたくなかった。しかし、私は正確に何をすべきですか?または私は何をgoogleする必要がありますか?あなたは私が巨大なjavascriptではないことを知っている=) –

答えて

8

[OK]をだから私は思います別々のフォームフィールドを正しくレンダリングする方法を見つけました。私はdjangoのソースを見てそれを見つけた。 Django.forms.forms.BaseFormクラスは_html_outputメソッドを持ち、Django.forms.forms.BoundFieldのインスタンスを作成し、次にunicode(boundField)をhtml出力に追加します。私はまったく同じことをしたし、それは完全に働いた:

#in templatetags/user_list_tags.py 
from django import template 
from django import forms 
register = template.Library() 

#this is djangp template tag for user selection form 
@register.filter 
def user_select_field(form, userid): 
    """ 
    returns UserSelectionForm field for a user with userid 
    """ 
    key = str(userid) 
    if key not in form.fields.keys(): 
     print 'Key %s not found in dict' % key 
     return None 
    #here i use BoundField: 
    boundField = forms.forms.BoundField(form, form.fields[key], key) 
    return unicode(boundField) 

{{form.as_p}}と同じHTMLを生成したことなので、POSTリクエストはまったく同じになりますと、フォームが正しく処理されます。

私も自分のフォームクラスでいくつかのミス固定:

#in UserSelectionForm definition: 
... 
#__init__ 
for f in userlist: 
    self.fields[str(f.id)] = forms.BooleanField(initial=False, required=False) 
#get_selected  
return filter(lambda u: self.cleaned_data[str(u.id)], 
    self.custom_fields) 

今私はjavascriptをせずに、計画通りに動作しているようです。

+3

[ソースコード](https://github.com/django/django/blob/master/django/forms/forms.py#L108)を読む私は、BoundFieldを使用する代わりに、より洗練された 'form [key ] 'と同じBoundFieldを取得します。 –

12

あなたはあまりにも複雑なテンプレートを作っている。あなたはそれを作成するときに、各フィールドにラベルを追加します。フォームの__init__方法。

for f in userlist: 
    self.fields[str(f.id)] = forms.BooleanField(label=f.username, initial=False) 

フォームのフィールドを超えるそれからちょうどループともうuserlistの心配はありません。

+0

残念ながら、私はこれを行うことはできません。私は例を明確にするためにコードを単純化しました。私のバージョンでは、このチェックボックスを持つテーブルの行には2つ以上の列があり、チェックボックスの他に別のウィジェットがあります(「選択方法」、すべてのユーザーを選択する天気を選択するか、チェックボックスでのみ選択します)。たぶん私は別々のフォームでそれらを分割しようとする必要がありますか?それはフォーム 'get_selected'メソッドのカプセル化を緩めるでしょうが、タスクを単純にするかもしれません。 –

関連する問題