Django - Динамическое добавление второй формы на страницу

Я ищу руководство по созданию динамической формы в Django, которая меняется в зависимости от того, какие участники находятся на встрече.

Предыстория такова: Приложение используется для отслеживания результатов встреч нескольких команд, каждая из которых состоит из 4-8 человек. В течение нескольких дней команда может провести 6 встреч. Для каждого собрания команда выбирает 1 или 2 членов в качестве участников собрания. На каждом собрании команда выдвигает участников таким образом, чтобы за время тренинга все члены команды приняли участие в одном или нескольких собраниях. На каждом собрании все остальные члены команды являются "Наблюдателями".

Проблема, с которой я столкнулся, заключается в том, как динамически вставить форму или поля формы для каждого из наблюдателей, учитывая, что количество наблюдателей может быть любым - от одного до 6. Идея заключается в том, чтобы позволить наблюдателям "оценивать" собрание и записывать этот результат в модель наблюдателя.

Представление ScoreCreate правильно устанавливает 1-го участника и заполняет выпадающий список "Другой участник" всеми остальными членами команды.

HTMX в шаблоне передает данные 1-го и, если выбран "другой участник", функции наблюдателей, которая затем разбирается, кто должен быть наблюдателем.

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

Мысли о том, как я могу подойти к этому, приветствуются.

МОДЕЛИ:

from .choices import SCORE_CHOICES, RATING_CHOICES

class Meeting(models.Model)
    date = models.DateTimeField(auto_now=True)

class Team(models.Model):
    # up to 8 members per team
    name = model.CharField(max_length=25)


class Participant(models.Model):
    name = model.CharField(max_length=25)
    team = model.ForeignKey(Team, on_delete.models.CASCADE)


class Score(models.Model):
# primary is required, secondary is not required
    meeting = models.ForeignKey('Meeting', on_delete.models.CASCADE)
    primary_participant = models.ForeignKey('Participant', on_delete.models.CASCADE)
    secondary_participant = models.ForeignKey('Participant', related_name='secondary_participant', on_delete.model.CASCADE, blank=True, null=True)
    score = models.CharField(max_length=25, choices = SCORE_CHOICES)


class Observer(models.Model):
    score = models.ForeignKey(Score, on_delete.models.CASCADE)
    observer = models.ForeignKey(Participant, on_delete.models.CASCADE)
    rating = models.CharField(max_length=1, choices=RATING_CHOICES)

ПРОСМОТРОВ:

class ScoreCreate(LoginRequiredMixin, CreateView):
    model = Score
    form_class = ScoreCreateForm
    template_name = 'score_create.html'

    def get_initial(self):
        participants = Participant.objects.filter(slug=self.kwargs['slug'])
        participant_id = self.kwargs['pk']
        other_participants = participants.filter(~Q(pk=self.kwargs['pk'])
    

def observers(request):
    participant = request.GET.get('participant')
    other_participant = request.GET.get('other_participant')
    team = request.GET.get('team')

    if other_participant:
        observers = Participant.objects.filter(~Q(id=participant) & ~Q(id=other_participant) & Q(team=team))

    else:
        observers = Participant.objects.filter(~Q(id=participant) & Q(team=team) & Q(role='PARTICIPANT'))

    return render(request, 'trial/partials/all_observers.html', context={'observers': observers})       

TEMPLATE: score.html

<form method="POST" name="score_participants">
<div class="d-flex">
    <div class="align-self-end g-color-primary text-uppercase g-letter-spacing-1 g-font-weight-800 g-my-10">Meeting Details
    </div>
    <div class="ml-auto">
        <input class="btn btn-md btn-warning g-mr-10 g-mb-15 g-rounded-50" onclick="location.href='#'" type="button"
               value="Cancel">
        <button class="btn btn-md u-btn-primary g-mr-0 g-mb-15 g-rounded-50" type="submit">Submit</button>
    </div>
</div>
<div class="d-flex g-mt-0 g-brd-top g-brd-gray-light-v3 g-bg-secondary">
    <div class="g-mt-12 g-ml-10">Participant:</div>
    <div>
        {{form.participant|as_crispy_field}}
    </div>
    <div class="ml-auto g-mt-13 g-mb-12 g-mr-10 g-color-primary text-uppercase g-letter-spacing-1 g-font-weight-600">{{participant}}</div>
</div>

<div class="d-flex g-mt-0 g-brd-top g-brd-gray-light-v3">
    <div class="g-mt-18 g-ml-10 g-mr-50">Meeting Number:</div>
    <div class="ml-auto g-mt-13 g-mr-10">{{form.meeting_number|as_crispy_field}}</div>
<div class="d-flex g-mt-0 g-brd-top g-brd-gray-light-v3 g-bg-secondary">
    <div class="g-mt-18 g-ml-10 g-mr-50">Name of other meeting participant:</div>
    <div class="ml-auto g-mt-13 g-mr-10"
        hx-get="{% url 'observers' %}"
         hx-include="[name='score_participants']"
        hx-trigger="change"
        hx-target = "#observers">
            {{form.other_participant|as_crispy_field}}
        </div>
    </div>

<div class="g-mt-0 g-brd-top g-brd-gray-light-v3">
    <div id="observers"></div>
</div>
...

TEMPLATE: observer.html

{% block content %}
    {% for observer in observers %}
<div class="d-flex">
    <div>{{observer}}</div>
    <div class="ml-auto">RATING (RADIO BUTTONS)</div>
</div>
{% endfor %}
{% endblock %}

Example with 1 participant

Example with 2 participants

Идея заключается в том, чтобы использовать представление, которое обрабатывает данные, поступающие с той страницы, которую вы показали, переходя на следующую страницу, которая показывает формы. Так что если вы просто пытаетесь показать формы на следующей странице, вы можете обрабатывать логику внутри вашего представления и сказать, что если есть 4 наблюдателя, то вы хотите иметь цикл for, который создает форму для каждого из них и добавляет их в список. Затем в HTMX вы можете для каждого из этого списка вывести эту форму, и вы можете использовать идентификаторы для каждого html объекта в forms.py и управлять ими в css.

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

Вернуться на верх