ユーザーが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に保存)、どれが選択されているかを知ることができます。
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