web-dev-qa-db-ja.com

django保存されたモデルのフォームドロップダウンリスト

ユーザーが2つのアクションを実行できるライブラリのフォームを作成しようとしています。新しいブックを追加するか、既存のブックの保存されている情報を開きます。書籍には2つのフィールド(タイトルと著者)があります。新しい本が作成されるたびに、データベースに保存されます。以前に作成したブックは、オプションとしてドロップダウンリストに表示されます(名前のみ)。ユーザーがドロップダウンリストからオプションを選択すると、選択した書籍の情報が画面に表示されます。

私は2つの異なるアプローチを試みてきましたが、どれも私の要件を満たしていません。一方では、この質問に続いて Djangoフォームのドロップダウンリストの数値 ドロップダウンリストを作成して、ビューで選択した値を次のようなコードで取得できます。

class CronForm(forms.Form):
    days = forms.ChoiceField(choices=[(x, x) for x in range(1, 32)])

def manage_books(request):
    d = CronForm()
    if request.method == 'POST':
        day = request.POST.get('days')

しかし、私は自分のオプションを、事前に定義された値ではなく、データベースに以前に保存した本にしたいと考えています。

私が試した他のアプローチは、htmlテンプレートから実行することです。そこで次のフォームを作成します。

<form>
    {% for book in list %} 
        <option value="name">{{ book.name }}</option>
    {% endfor %}   
</form>

これからのビューで本がレンダリングされる場所:

l = Books.objects.all().order_by('name')

この2番目のケースでは、ドロップダウンリストに表示される情報が必要ですが、選択した値を取得してビューで使用する方法がわかりません。おそらくJavaScript関数を使用していますか?

したがって、私の2つの要件は次のとおりです。正しい情報をリストに表示し(ユーザーがDBに保存)、どれが選択されているかを知ることができます。

16
toni

ModelChoiceField を使用する必要があります。

class CronForm(forms.Form):
    days = forms.ModelChoiceField(queryset=Books.objects.all().order_by('name'))

次に、ビューは次のようになります。

def show_book(request):
   form = CronForm()
   if request.method == "POST":
      form = CronForm(request.POST)
      if form.is_valid:
         #redirect to the url where you'll process the input
         return HttpResponseRedirect(...) # insert reverse or url
   errors = form.errors or None # form not submitted or it has errors
   return render(request, 'path/to/template.html',{
          'form': form,
          'errors': errors,
   })

新しい本を追加または編集するには、 ModelForm を使用する必要があります。次に、そのビューで、それが新しいフォームかどうかを確認します

book_form = BookForm() # This will create a new book

または

book = get_object_or_404(Book, pk=1)
book_form = BookForm(instance=book) # this will create a form with the data filled of book with id 1
35
J. Ghyllebert