Python django 表单存储模型的下拉列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16055808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 21:40:54  来源:igfitidea点击:

django form dropdown list of stored models

pythonhtmldjangoforms

提问by toni

I am trying to create a form for a library where a user can perform 2 actions: add a new book or open the stored information of an existing one. Books have 2 fields (title and author). Every time a new book is created, it is stored at the database. Any previously created book is shown as an option at a dropdown list (only the name). I want that when a user selects an option from the dropdown list, the information of the selected book appears on screen.

我正在尝试为图书馆创建一个表单,用户可以在其中执行 2 项操作:添加新书或打开现有书籍的存储信息。书籍有 2 个字段(标题和作者)。每次创建新书时,它都会存储在数据库中。任何以前创建的书籍都显示为下拉列表中的一个选项(仅名称)。我希望当用户从下拉列表中选择一个选项时,所选书籍的信息会出现在屏幕上。

I have been trying 2 different approaches, but none of them fulfills my requirements. On one hand, following this question django form dropdown list of numbersI am able to create a dropdown list, and get the selected value at views with some code like that:

我一直在尝试两种不同的方法,但它们都不能满足我的要求。一方面,按照这个问题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')

But I want my options to be the previously stored books at the data base, and not pre-defined values.

但我希望我的选项是以前存储在数据库中的书籍,而不是预定义的值。

An other approach I have tried is to do it from the html template. There I create the following form:

我尝试过的另一种方法是从 html 模板中进行。在那里我创建了以下表单:

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

Where book is rendered at views from this:

在此视图中呈现书籍的位置:

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

In this second case the information shown at the dropdown list is the one I want, but I don't know how to get the selected value and use it at views. Perhaps using a javascript function?

在第二种情况下,下拉列表中显示的信息是我想要的信息,但我不知道如何获取所选值并在视图中使用它。也许使用javascript函数?

So my 2 requirements are: show the correct info at the list (the stored at the DB by the user) and be able to know which one has been selected.

所以我的 2 个要求是:在列表中显示正确的信息(用户存储在数据库中)并且能够知道选择了哪一个。

采纳答案by J. Ghyllebert

You should use ModelChoiceField.

您应该使用ModelChoiceField

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

Then your views, it should look something like this:

然后你的观点,它应该是这样的:

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,
   })

To add a new book or edit one, you should use a ModelForm. Then in that view you'll check if it's a new form or not

要添加新书或编辑新书,您应该使用ModelForm。然后在该视图中,您将检查它是否是新表单

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

or

或者

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