Django Назначение разных внешних ключей разным формам в наборе форм

Summary

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

Требование к дизайну №1

  • Я работаю с требованием к дизайну, где пользователь должен нажать на кнопку, чтобы добавить форму на сайт. кнопку, чтобы добавить форму PollQuestion на сайт. Кнопка может быть нажать несколько раз, чтобы добавить несколько форм PollQuestion, а при представление будет создавать экземпляры PollQuestion, которые будут связаны с одной и той же формой . связанные с одним и тем же Poll объектом через внешний ключ.

Выполнение

  • В настоящее время я использую modelfactory_formset и DOM манипуляции с JavaScript для динамического добавления PollQuestion форм в DOM, которые при отправке обрабатываются в представлении как набор форм. Это работает нормально.

Требование дизайна 2

  • Design также хочет иметь возможность динамически добавлять PollOption формы к форму PollQuestion с помощью HTML-кнопки. Одна кнопка submit будет отправлять данные из обеих форм PollQuestion и PollOption в представление для обработки.

Выполнение

  • И снова я использую динамический набор форм modelfactory_formset для форм PollOption. Кнопка "Добавить опцию" добавляет форму PollOption в DOM. Это отлично работает, если у меня есть только одна форма PollQuestion.

Проблема

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

Как я могу реализовать эту функцию? Возможно ли вообще сделать это в представлении Django или мне нужно рассмотреть другой подход?

У меня есть модели, которые связаны через внешние ключи:

#models.py

class Poll(models.Model):
   title = models.CharField(default="", max_length=100, blank=True)

class PollQuestion(models.Model):
    title = models.CharField(default="", max_length=100, blank=True)
    poll = models.ForeignKey(
        "poll.Poll",
        related_name="polls",
        on_delete=models.CASCADE,
    )

class PollOption(models.Model):
    title = models.CharField(default="", max_length=100, blank=True)
    poll_question = models.ForeignKey(
        "poll.PollQuestion",
        related_name="poll_questions",
        on_delete=models.CASCADE,
    )

Каждая модель имеет прямую форму модели.

#forms.py

class PollForm(forms.ModelForm):
    class Meta:
        model = Poll
        fields = [
            "title",
        ]

class PollForm(forms.ModelForm):
    class Meta:
        model = Poll
        fields = [
            "title",
        ]

class PollQuestionForm(forms.ModelForm):
    class Meta:
        model = PollQuestion
        fields = [
            "title",
        ]

PollQuestionFormSet = modelformset_factory(
    PollQuestion,
    form=PollQuestionForm,
    extra=1,
)

PollOptionFormSet = modelformset_factory(
    PollOption,
    form=PollOptionForm,
    extra=1,
)

А вот часть представления:

...
poll = Poll()

if request.method == "POST":
        poll_form = PollForm(request.POST, request.FILES, instance=poll, initial=initial)
        poll_question_formset = PollQuestionFormSet(
            request.POST,
            request.FILES,
            queryset=PollQuestion.objects.none(),
            prefix="questions",
        )
        poll_option_formset = PollOptionFormSet(
            request.POST,
            request.FILES,
            queryset=PollOption.objects.none(),
            prefix="options",
        )
        if poll_form.is_valid():
            poll = poll_form.save(commit=False)
            poll.save()
            if poll_question_formset.is_valid():
                poll_question_forms = poll_question_formset.save(commit=False)
                for poll_question in poll_question_forms:
                    poll_question.poll = poll
                    poll_question.save()
                poll_question_formset.save()
                if poll_option_formset.is_valid():
                    poll_option_forms = poll_option_formset.save(commit=False)
                    for poll_option in poll_option_forms:
                        poll_option.poll_question = poll_question
                        poll_option.save()
                    poll_option_formset.save()
...
Вернуться на верх