2012-04-19 19 views
3

これらのフィールドは固定されていない、特定のフィールドをModelFormに更新しようとしています。Django - ModelForm動的フィールド更新

class Session(models.Model): 
    tutor = models.ForeignKey(User) 
    start_time = models.DateTimeField() 
    end_time = models.DateTimeField() 
    status = models.CharField(max_length=1) 

フォーム::私だけend_timeを更新する必要があり、時には特定のセッションに対する

class SessionForm(forms.ModelForm): 
    class Meta: 
    model = Session 
    exclude = ['tutor'] 

、時々だけstart_time &

モデル(私はビューでautopopulatedれるだけtutorを持っています) end_time

ビューでどのように行うことができますか?


編集

私は例を与えているが、それはこれらの例に限定されていない、私は更新する必要があるフィールドが事前に定義されていない、私は、任意のフィールド(複数可)を更新できるようにする必要があります

+0

「更新」と言ったら、どういう意味ですか?すべてのフォームフィールドをレンダリングするのか、それとも更新するフォームフィールドだけをレンダリングしますか? – okm

+0

更新されたものだけをレンダリングします。 (私は値を変更することを意味する更新) –

+0

これは、使用シーンのように例を取ることができますか?あなたの目的はまだよく分かりません。 – okm

答えて

8

class SessionForm(forms.ModelForm): 
    class Meta: 
     model = Session 
     exclude = ['tutor', 'start_time'] 

    def __init__(self, your_extra_args, *args, **kwargs): 
     super(SessionForm, self).__init__(*args, **kwargs) 
     if need_end_time_start_time(your_extra_args): 
      self.fields['start_time'] = forms.DateTimeField()  

は、このクラスを使用するには、フォームに引数「your_extra_args」を渡す必要がありますこれまでと似たようなものですが、それほど正確ではありませんが、かなり効果的です。実行時に型を動的に作成し、その型を使用します。いくつかのドキュメントについては、DynamicModels for django.

をご覧ください。

  • あなたは、フォームあなたが選択フィールドが

ので、実行時に更新されるかを指定します

  • を使用してモデルを更新することができるようにしたい、いくつかのコード:

    def create_form(model, field_names): 
        # the inner class is the only useful bit of your ModelForm 
        class Meta: 
         pass 
        setattr(Meta, 'model', model) 
        setattr(Meta, 'include', field_names) 
        attrs = {'Meta': Meta} 
    
        name = 'DynamicForm' 
        baseclasses = (forms.ModelForm,) 
        form = type('DynamicForm', baseclasses, attrs) 
        return form 
    
    def my_awesome_view(request): 
        fields = ['start_time', 'end_time'] 
        form = create_form(Session, fields) 
        # work with your form! 
    
  • +0

    私はこれが好きです。かわいいのは何? –

    +0

    私はそれは直感的ではないと言わなければならない。私は動的テーブルの実装について考えているときに「あまりにもいい」コメントを書いていました。これは実際にかなりエレガントに見えます。 –

    +0

    直接フォームを生成して返さないのはなぜですか? 'type()'で構築するのは 'attrs'に動的なフィールドを持つ動的モデルに便利です。' attrs'には 'Meta'クラスしかありません。とにかく。 – okm

    1

    NULL可能としますが、フィールドの元にロジックを追加することができ、「クリーン」な方法と同様に、フォームフィールドを置く:あなたは、CHたい場合

    class SessionForm(forms.ModelForm): 
        def clean_end_date(self): 
         cd = self.cleaned_data 
         if (cd["start_date"] and cd["end_date"]) and cd["end_date"] < cd["start_date"]: 
          raise forms.ValidationError("WTF?!") 
         if not (cd["start_date"] or cd["end_date"]): 
          raise forms.ValidationError("need one date") 
         return cd['end_date'] 
    

    をange値は、return文とは異なる値を使用します。

    これは、検証に必要なものです。

    したい場合、あなたはそれが助けたいと考えている

    インスタンス化するフォーム

    def my_view(request): 
        r_data = request.GET.copy() 
        r_data.merge(request.POST) 
    
        data = dict([(key, my_function(key, value)) for key, value in r_data.iteritems() if key in MyForm.fields]) 
        form = MyForm(data=data) 
        [...] 
    
    前に、あなたのビューおよび更新値で辞書をGETコピーすることができます。

    +0

    私の質問に正確には反応しませんが、検証ルールが面白いです、私はそれらを使用します:) –

    0

    あなたはこのように、フォームのコンストラクタを呼び出すことができます。私がしなければならなかった

    session_form = SessionForm('foo') 
    
    +0

    10個のフィールドを持つモデルがあり、それぞれが独立して更新可能な場合は、それぞれを行う必要がありますか? –

    +0

    その場合、更新するルールを正しく設定する必要がありますか? 10フィールドの名前にfield_1、field_2、...のような名前を付けて、ループを使用して1つのステップで行う必要があります。 – vutran

    +0

    を使用するか、kwargsを使用すると、setattrを使用して値を簡単に変換できます。しかし、私はあなたの投稿をコピー/クエリのdictを取得し、ビューでそれを変更することはあなたのために良い方法かもしれない、あなたはフィールドにeterateし、あなたがフォームを介してあなたの変更を検証することを計算することができるでしょう。 – christophe31

    0

    あなたのニーズは、同じモデルを使用するが、あなたのニーズに応じて、異なるフィールドがModelFormに隠されていることを示唆しています。

    あなたの質問を理解したら、2つの異なるModelFormベースのクラスを作成する必要があります。これらのクラスはどちらもMetaクラス内で同じモデル値を持ちます。除外して必要なフィールドを追加します。これで、ビューロジック内で呼び出すことのできるさまざまなModelFormクラスが作成されました。

    これにより、同じモデルに依存する2つの異なるフォームが異なるデフォルトフィールドで使用されます。

    賢明なURLとビューデザインを使用すると、上記の考えを使用して同じモデルから複数のフォームを配信できます。

    関連する問題