15

私は django フォームを理解するのに苦労しています。さまざまなドキュメントを読んでいますが、概念を完全に理解することはできません。モデル、ビュー、およびテンプレートを把握する必要があります。私がやろうとしているのは、データベース内の値が取り込まれるドロップダウン リストとチェックボックスで構成されるさまざまなフィールドを持つフォームを作成することです。

私はvmsと呼ばれる作業アプリを持っています。models.py を使用して、サイズとタイプを保持する単純なスキーマを作成しました。サイズは「小」「中」「大」で構成されています。タイプは「windows」と「linux」です。管理サイトを使用して、「特大」などの特別なサイズを追加できます。

私がやりたいのは、vm サイズのドロップダウン リストを持つフォームを作成することです。管理サイトから追加のサイズが追加された場合、そのサイズをドロップダウン リストに表示したいと思います。

コードの試みを提出しますが、実際には概念に苦労しています。上記を達成する方法を教えてくれる人はいますか?

ありがとうオリ

4

3 に答える 3

36

フォームは、リクエストから POST データを取得するプロセス (の開発) を簡素化および高速化するための単なるツールです。手動の方法はrequest.POST.get('somefield')、HTML フォームにあるすべてのフィールドに対して行うことです。しかし、Django はそれよりもうまくやることができます...

本質的に、フォーム クラスは多数のフィールドを保持し、次のタスクを実行します。

  1. HTML 入力の表示、
  2. ユーザーがデータを送信したときにデータを収集して検証する
  3. フィールドが検証されない場合は、エラー メッセージとともに値を HTML に返します。
  4. すべてのフィールドが有効form.cleaned_dataな場合は、ビュー内のこれらの値にアクセスするための便利な方法としてディクショナリを提供します。

これらの値を使用して、a の新しいインスタンスを手動で作成し、MyModel保存することができます。もちろん、MyModel モデルのすべての Field に対して Form で Field を定義する必要があります。

これは、基本的に、次のようなことができることを意味します:
(このコードをテストしていないことを許してください。100% 正しいとは保証できません)

models.py:

    class MyModel(models.Model):
        field1 = models.CharField(max_length=40, blank=False, null=False)
        field2 = models.CharField(max_length=60, blank=True, null=True)

forms.py:

    class FormForMyModel(forms.Form):
        form_field1 = forms.CharField(max_length=40, required=True)
        form_field2 = forms.CharField(max_length=60, required=False)

views.py:

    def create_a_my_model(request):
        if request.method == 'POST':
            form = FormForMyModel(request.POST)
            if form.is_valid():
                my_model = MyModel()
                my_model.field1 = form.cleaned_data.get('form_field1', 'default1')
                my_model.field2 = form.cleaned_data.get('form_field2', 'default2')
                my_model.save()
        else:        
            form = FormForMyModel()
        context_data = {'form': form}
        return HttpResponse('templtate.html', context_data)

(これは数行少ないコードで記述できますが、可能な限り明確にすることを目的としています)

モデル フィールドとフォーム フィールドの間には関係がないことに注意してください。作成時に MyModel インスタンスに手動で値を割り当てる必要があります。

上記の例は、一般的なフォーム ワークフローの概要を示しています。複雑な状況で必要になることがよくありますが、この例のような単純な状況では必要ありません。

この例 (および実世界の多くの例) では、Django はそれよりも優れた処理を実行できます...

上記の例で 2 つの厄介な問題に気付くことができます。

  1. MyModelFields onと Fields on をFormForMyModel別々に定義する必要があります。ただし、フィールドのこれら 2 つのグループ (タイプ) には多くの類似点があるため、重複作業のようなものです。ラベル、バリデーターなどを追加すると、類似性が高まります。
  2. インスタンスの作成はMyModel少しばかげており、これらすべての値を手動で割り当てる必要があります。

ここでModelFormの出番です。

これらは基本的に通常のフォームと同じように機能します (実際には、通常のフォームから拡張されています) が、作業の一部を節約できます (もちろん、今概説した 2 つの問題:))。

では、2 つの問題に戻ります。

  1. モデル フィールドごとにフォーム フィールドを定義する代わりにmodel = MyModelMetaクラスで定義するだけです。これは、モデル フィールドからフォーム フィールドを自動的に生成するようにフォームに指示します。

  2. モデルフォームにはsave利用可能なメソッドがあります。これを使用して、フィールドごとに手動で割り当てる代わりに、ビュー内の 1 行でモデルのインスタンスを作成できます。

それでは、上記の例をModelForm:

models.py:

    class MyModel(models.Model):
        field1 = models.CharField(max_length=40, blank=False, null=False)
        field2 = models.CharField(max_length=60, blank=True, null=True)

forms.py:

    class MyModelForm(forms.ModelForm):  # extending ModelForm, not Form as before
        class Meta:
            model = MyModel

views.py:

    def create_a_my_model(request):
        if request.method == 'POST':
            form = MyModelForm(request.POST)
            if form.is_valid():
                # save the model to database, directly from the form:
                my_model = form.save()  # reference to my_model is often not needed at all, a simple form.save() is ok
                # alternatively:
                # my_model = form.save(commit=False)  # create model, but don't save to database
                # my.model.something = whatever  # if I need to do something before saving it
                # my.model.save()
        else:        
            form = MyModelForm()
        context_data = {'form': form}
        return HttpResponse('templtate.html', context_data)

これにより、Django フォームの使用法が少し明確になることを願っています。

もう 1 つ注意してくださいModelForm。これらは使用されませんが、通常のフォームと同じようにform.save()アクセスできます。form.cleaned_data

于 2012-08-12T18:19:59.017 に答える
2

以前にModelFormsを使用してみましたか?私が理解しているように、あなたはあなたが正しく作成したモデルに基づいてフォームを作成しようとしていますか?

モデルがTempと呼ばれているとしましょう。次のように、このモデル(および質問)と相関するフォームを作成できます。

forms.py

from django.forms import ModelForm

class TempForm(ModelForm):
  class Meta:
    model = Temp

ModelFormは、モデルからの選択/選択をフォームバージョンに自動的にマップします。

後でテンプレートでこれを使用することを計画している場合、このようなことを行うと、選択肢のあるドロップダウンメニューが自動的に作成されます。

<form>
  <label for="id_size">Size</label>
  {{ form.size }}
</form>

それがあなたの質問に答えることを願っています!

于 2012-08-12T17:21:23.293 に答える