Django: ModelMultipleChoiceField не работает, когда модель формы не та, в которой определено поле ManyToMany, а "другой класс"

Я пытаюсь создать инструмент управления персоналом мероприятия на Django. Одна часть модели данных состоит в том, что сотрудник (класс Staff) связан с запланированной сменой (ScheduledEventShift) через ManyToManyField через StaffShift.

Каждый сотрудник может видеть доступные для него/нее смены и выбирать их через ModelMultipleChoiceField. Это прекрасно работает, и отношение корректно записывается в таблицу StaffShift в зависимости от того, отмечена смена или нет.

(извините, что инструмент на немецком, но из контекста должно быть понятно, что я имею в виду)

enter image description here

enter image description here

Сейчас я хочу сделать "обратное", т.е. я как администратор хочу посмотреть на одну смену, увидеть, какие сотрудники подали заявки на эту смену и снять галочки с тех, которых "слишком много" (т.е. требуется 2, подано 3).

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

enter image description here

Вот соответствующая часть моего кода:

models.py:

class Staff(models.Model):
    <...>
    shifts = models.ManyToManyField(ScheduledEventShift, through='StaffShift', related_name='applied_staff')

forms.py:

class ScheduledEventShiftEditForm(forms.ModelForm):

    class Meta:
        model = ScheduledEventShift
        fields = ['shift_count_required', 'applied_staff', 'event_shift_info']

    shift_count_required = models.IntegerField()
    applied_staff = forms.ModelMultipleChoiceField(
        queryset=None,
        widget=forms.CheckboxSelectMultiple)

views.py:

class ScheduledEventShiftUpdateView(ObjectUpdateView):
    model = ScheduledEventShift
    form_class = ScheduledEventShiftEditForm
    <...>

    def get_form(self, form_class=None):
        form = super().get_form(form_class=self.form_class)
        form.fields['applied_staff'].queryset = ScheduledEventShift.objects.filter(
            id=self.kwargs.get('pk')).first().applied_staff.all()

Является ли такое отношение ManyToMany со сквозной таблицей не идеально симметричным (т.е. связанные модели могут использоваться одинаково с обеих сторон)? Должен ли я делать это по-другому, если моя модель для формы - это не класс, в котором определены поля ManyToManyField и сквозная таблица, а "другой класс"? Большое спасибо

Поскольку staff не является полем в модели Shift, мы должны вручную установить начальное значение для поля и также вручную сохранить изменения

class ShiftUpdateForm(ModelForm):

    class Meta:
        model = Shift
        fields = ['shift_name', 'staff']

    shift_name = forms.CharField(max_length=32)
    staff = forms.ModelMultipleChoiceField(
        queryset=Staff.objects.all(),
        widget=forms.CheckboxSelectMultiple
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['staff'].initial = self.instance.staff.all()

    def save(self, *args, **kwargs):
        instance = super().save(*args, **kwargs)
        instance.staff.set(self.cleaned_data['staff'])
        return instance
Вернуться на верх