Как добавить выбор из представления?

Я пытаюсь динамически заполнить два поля выбора формы, а именно person и work.

Представление под названием assign_work_to_person должно позволить пользователю выбрать человека, произведение, которое еще не назначено человеку, и после отправки формы выбранное произведение должно быть связано с выбранным человеком (например, «Леонардо да Винчи» должен быть связан с «Моной Лизой»).

Что я делаю, так это создаю класс формы с пустыми вариантами для двух полей.

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

а затем извлечение доступных лиц и незарегистрированных работ для заполнения полей формы, когда пользователь обращается к представлению assign_work_to_person.

Я пытаюсь динамически установить эти варианты таким образом:

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

Когда я получаю доступ к представлению, шаблон отображается нормально, и все доступные варианты отображаются правильно.

введите здесь описание изображения

Проблема в том, что когда я отправляю форму, она вызывает ошибки проверки для обоих полей, предлагая мне выбрать правильный вариант.

введите здесь описание изображения

Запустив некоторые (очень простые) тесты печати, я понял, что попытка заполнить поля таким образом фактически не добавляет вариантов, даже если они есть в шаблоне. На самом деле, как вы можете видеть на втором рисунке, как только я отправил форму, шаблон отображает форму без каких-либо доступных вариантов.

Как я могу заставить это работать?

Из других ответов на подобные вопросы я знаю, что это можно сделать, указав метод __init__ в модели (в моем случае, я полагаю, форму), а затем установив варианты через аргумент ключевого слова queryset, но я бы предпочел сделать это в представлении, если это возможно.

Редактировать

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)

person Mirko Oricci    schedule 18.02.2020    source источник
comment
В какой функции вы заполняете поля? get_form() было бы хорошим местом, поскольку оно вызывается как в GET, так и в POST.   -  person AKX    schedule 18.02.2020
comment
Я делаю это прямо из представления, а не из функции. Должен ли я объявить функцию/метод внутри представления для получения кортежей?   -  person Mirko Oricci    schedule 18.02.2020
comment
@MirkoOricci Можете ли вы опубликовать свой код просмотра?   -  person Nafees Anwar    schedule 18.02.2020
comment
у вас есть обработка js на вашей странице?   -  person Brown Bear    schedule 18.02.2020
comment
да, я делаю это сейчас :)   -  person Mirko Oricci    schedule 18.02.2020
comment
@NaafesAnwar Представление немного беспорядочное, потому что я печатал переменные...   -  person Mirko Oricci    schedule 18.02.2020
comment
@BearBrown Нет, на данный момент я пытаюсь использовать только Django, Python, CSS и HTML.   -  person Mirko Oricci    schedule 18.02.2020


Ответы (1)


Вы повторно инициализируете форму


print(form.fields['person'].choices)
form = AssignWorkToPerson(request.POST)

if form.is_valid():

Это должно быть так


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

form = AssignWorkToPerson(request.POST) должен быть сверху сразу после проверки метода, а не в конце.

person Nafees Anwar    schedule 18.02.2020