2012-02-08 10 views
3

私は、何かのものの上に未知数のヘルパーを保存する必要のあるモデルフォームを持っています。名前は保存時にシリアル化することができますが、それは問題ではありません。それは、投稿時にそれらをきれいにして検証することができます。JavaScriptとJSONFieldを使用してDjangoフォームに動的にフィールドを追加する

フォームは次のようになります。

class ThingForm(forms.ModelForm): 
    """ 
    Form for the Thing 
    """ 
    owner = forms.CharField() 
    helpers = forms.CharField() 

    class Meta: 
     model = Thing 

    def save(self, *args, **kwargs): 
     """ 
     Serialize helpers to JSON. 
     """ 
     ... 

モデルはJSONFieldを使用してシリアル化されたヘルパーを格納しています。

class Thing(models.Model): 
    owner = models.CharField() 
    helpers = JSONField() 

私は同じ入力された名前と、必要に応じJavaScriptができるだけ多くのヘルパーを追加することがあります。ヘルパーのタプルを返して

<input name="helpers" value="Fred" /> 
<input name="helpers" value="Joe" /> 

問題はフォームが有効でない場合 - その名前は失われますとクリーニングが機能していないことです。

私が最初に考えたのは、フォームのコンストラクタに追加することでした:

def __init__(self, *args, **kwargs): 
     super(ThingForm, self).__init__(*args, **kwargs) 
     try: 
      helpers = args[0].pop('helpers') 
      for name in helpers: 
       # Add a charfield, or something? 
     except: 
      pass 

しかし、私は本当にどこにも届かない...

答えて

0

私はあなたがする必要があるすべては、こののように何かをするだと思いますお使いのテンプレート:あなたのフォームにprefix kwargを渡して起動した場合、これが壊れること

{% if form.data %}{# eg, was invalid and this is a re-render w/ errors #} 
{% for helper in form.data.helpers %} 
<input type="hidden" name="helpers" value="{{ helper }}"> 
{% endfor %} 
{% endif %} 

注 - しかし、そう、あなたの元のコードは、でしょう、別の問題である定着:)

+0

問題は、余分なヘルパーがフォームでクリーンアップされるため、テンプレートが取得されるまでに存在しないことです。 – Wil

+0

これは追加したクリーンメソッドですか?エラーをレンダリングするために、 'request.POST'でバインドされたフォームをテンプレートに戻している間は、' form.data'のままでなければなりません。 – AdamKG

+0

いいえ、フォームはかなりバニラです。テンプレート内のイテレータを使用すると、最後の入力の文字が繰り返し処理されます(form.data.helpersに文字列があります)。 – Wil

0

これに対する答えはAdamKGです。あなたは再びあなたのビューでリストを使用することができます。

ビュー:

if request.method == 'POST': 
    helpers = request.POST.getlist('helpers') 
    form = ThingForm(request.POST) 
    if form.is_valid(): 
     form.save() 
     return HttpResponseRedirect('/saved/') 
else: 
    helpers = None 
    form = ThingForm() 

return render_to_response('my_template.html', 
    {'helpers': helpers, 'form': form}, 
    context_instance=RequestContext(request)) 

をテンプレート:

{% for field in form %} 
    {% if field.name == 'helpers' %} 
     {% for name in helpers %} 
      <input name="helpers" value="{{ name }}" /> 
     {% endfor %} 
    {% else %} 
     {{ field }} 
    {% endif %} 
{% endfor %} 
関連する問題