Присвойте значения каждой форме в форме набора в Django

Я пытаюсь создать набор форм, каждый из которых содержит поле ввода. Это будет иметь некоторое динамическое количество элементов, и после отправки формы введенный текст будет назначен в качестве "тегов" для связанного объекта. Это может показаться запутанным, поэтому давайте посмотрим на класс формы, который я пытаюсь создать:

class TagsForm(forms.Form):

    tags = forms.CharField()
    def __init__(self, *args, **kwargs):
        applicantId = kwargs.pop('applicantId')

    def saveTags(self):
        applicant = Applicants.objects.get(id=applicantId)
        Tag.update(applicant,tags)

Как вы можете видеть, я хотел бы передать форму идентификатору кандидата, после получения запроса на публикацию обновите тег для этого объекта кандидата, вызвав каждую форму saveTags. Вот код с моей точки зрения, где я занимаюсь этим:

    ...
    applicantQuery = allApplicantsQuery.filter(**kwargs)
    TagsFormSet = formset_factory(TagsForm)
    if request.method == 'POST':
        tags_formset = TagsFormSet(request.POST, request.FILES, prefix='tags')
        if tags_formset.is_valid()
            for tagForm in tags_formset:
                tagForm.saveTags()
    else:
        tags_formset = TagsFormSet(prefix='tags')
    ...

Проблема в том, что я не знаю, как создать начальный набор форм с идентификаторами из набора запросов ANTQuery. В идеале я мог бы просто пройтись по набору запросов и отправить antant.id в каждую форму, но я не уверен, как это сделать. Мне также кажется, что я должен упомянуть, что набор форм должен иметь точно такое же количество форм, как и кандидаты в ApplicantsQuery.

1 ответ

Решение

Вы можете написать собственный набор форм.

from django.forms.formsets import BaseFormSet

class TagFormSet(BaseFormSet):

    def __init__(self, *args, **kwargs):
        applicants = kwargs.pop('applicants')
        super(TagFormSet, self).__init__(*args, **kwargs)
        #after call to super, self.forms is populated with the forms

        #associating first form with first applicant, second form with second applicant and so on
        for index, form in enumerate(self.forms):
            form.applicant = applicants[index]

Теперь вам не нужно переопределять __init__ TagsForm.

Теперь каждая ваша форма связана с заявителем. Таким образом, вы можете удалить первую строку вашего saveTags(), Так что saveTags() становятся:

def saveTags(self):
    #applicant was set on each form in the init of formset
    Tag.update(self.applicant, tags)

Ваш код просмотра:

applicantQuery = allApplicantsQuery.filter(**kwargs)

#notice we will use our custom formset now
#also you need to provide `extra` keyword argument so that formset will contain as many forms as the number of applicants
TagsFormSet = formset_factory(TagsForm, formset=TagFormSet, extra=applicantQuery.count())

if request.method == 'POST':
    tags_formset = TagsFormSet(request.POST, request.FILES, prefix='tags', applicants=applicantQuery)
    if tags_formset.is_valid()
        for tagForm in tags_formset:
            tagForm.saveTags()
else:
    tags_formset = TagsFormSet(prefix='tags', applicants=applicantQuery)
Другие вопросы по тегам