如何从视图中添加选择?

How to add choices from a view?

我正在尝试动态填充两个表单选择字段,即 personwork

名为 assign_work_to_person 的视图应该允许用户 select 一个人,一个尚未分配给一个人的作品,一旦提交了表单 select ed 作品应链接到 selected 人(例如 'Leonardo da Vinci' 应链接到 'Mona Lisa')。

我正在做的是创建表单 class,两个字段的选择都是空的

class AssignWorkToPerson(forms.Form):
    person = forms.ChoiceField()
    work = forms.ChoiceField()

然后在用户访问 assign_work_to_person 视图时检索可用人员和无作者作品以填充表单字段。

我正在尝试以这种方式动态设置这些选项:

form.fields['the_field_name'].choices = a_list_of_tuples 

当我访问视图时,模板呈现正常,所有可用选项都正确显示。

问题是当我提交表单时,它会引发两个字段的验证错误,告诉我 select 一个有效的选择。

通过 运行 一些(非常基本的打印)测试,我意识到尝试以这种方式填充字段实际上并没有添加选项,即使它们存在于模板中。事实上,正如您从第二张图片中看到的那样,一旦我提交了表单,模板就呈现了没有可用选项的表单。

我怎样才能使这个工作?

我从类似问题的其他答案中得知,这可以通过在模型中指定一个 __init__ 方法(我想在我的例子中是表单),然后通过查询集设置选项来完成关键字参数,但如果可能的话,我宁愿在视图中这样做。

编辑

def assign_work_to_person(request):
    form = AssignWorkToPerson()
    persons = Person.objects.all()
    person_choices = []
    for person in persons:
        person_choices.append((person.first_name + ' ' + person.last_name, person.first_name + ' ' + person.last_name))
    form.fields['person'].choices = person_choices
    works = Work.objects.all()
    work_choices = []
    for work in works.filter(author=None):
        work_choices.append((work.name, work.name))
    form.fields['work'].choices = work_choices

    if request.method == 'POST':
        persons = Person.objects.all()
        person_choices = []
        for person in persons:
            person_choices.append(
                (person.first_name + ' ' + person.last_name, person.first_name + ' ' + person.last_name))
        form.fields['person'].choices = person_choices
        works = Work.objects.all()
        work_choices = []
        for work in works.filter(author=None):
            work_choices.append((work.name, work.name))
        form.fields['work'].choices = work_choices
        print(form.fields['person'].choices)
        form = AssignWorkToPerson(request.POST)

        if form.is_valid():

            print('THIS FORM CONTAINS VALID DATA')
    template_name = 'assign_work_to_person.html'
    context = {'form': form}
    return render(request, template_name, context)

您正在重新初始化表单


print(form.fields['person'].choices)
<b>form = AssignWorkToPerson(request.POST)</b>

if form.is_valid():

应该是这样的


   if request.method == 'POST':
        <b>form = AssignWorkToPerson(request.POST)</b>
        # skipped
        form.fields['person'].choices = person_choices  
        if form.is_valid():
            pass

form = AssignWorkToPerson(request.POST) 应该在方法检查之后而不是最后。