我正在尝试为库创建表单,用户可以在其中执行2个操作:添加新书或打开现有存储的信息。书籍有2个字段(标题和作者)。 每次创建新书时,它都存储在数据库中。任何以前创建的书籍都会在下拉列表中显示为一个选项(仅限名称)。我希望当用户从下拉列表中选择一个选项时,屏幕上会显示所选书籍的信息。
我一直在尝试两种不同的方法,但它们都没有满足我的要求。 一方面,关注这个问题django form dropdown list of numbers我可以创建一个下拉列表,并在视图中获取所选值,并使用如下代码:
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')
在第二种情况下,下拉列表中显示的信息是我想要的信息,但我不知道如何获取所选值并在视图中使用它。也许使用javascript函数?
所以我的2个要求是:在列表中显示正确的信息(由用户存储在DB中),并且能够知道哪个被选中。
答案 0 :(得分:30)
您应该使用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
答案 1 :(得分:0)
J。Ghyllebert对评论中的呈现问题的回答的补充。 模板渲染:
<form action="" class="YourFormClass" method="post">
{% csrf_token %}
{{ form.as_p }}
</form>
或单个字段:
<form action="" class="YourFormClass" method="post">
{% csrf_token %}
<label class="YourLabelClass">{{ form.days.label }}</label>
<div class="YourSelectClass">
{{ form.days }}
</div>
</form>
文档:https://docs.djangoproject.com/en/3.1/topics/forms/#the-template