Как указать варианты полей в django inlineformset

Я хочу отобразить только подмножество вариантов для поля формы модели. Например, в зависимости от url, на котором находится пользователь, я могу захотеть отобразить только "увеличение веса" и "паркинсонизм" в качестве вариантов для поля "se_name".

Я могу понять, как получить url в качестве параметра в представлении (p = self.request.GET.get("p", None)), но я не могу понять, как использовать этот параметр для ограничения доступного выбора.

Это набор форм

SideeffectFormSet = inlineformset_factory(
    Case,
    SideEffect,
    fields=("se_name",),
    widgets={'concern': RangeInput()},
    extra=0,
    min_num=1,
    validate_min=True,
)

В основе модели:

class SideEffect(TimeStampedModel):

    SE_CHOICES = [
        ("weight_gain", "Weight Gain"),
        ("parkinsonism", "Parkinsonism"),
        ("dystonia", "Dystonia"),
        ("none", "None"),
    ]

    se_name = models.CharField("",max_length=200, choices=SE_CHOICES, default="none")

    case = models.ForeignKey(Case, on_delete=models.CASCADE)

И форма отображается этим представлением:

class CaseView(LoginRequiredMixin, TemplateView):
    model = Case
    template_name = "se_balance/se_balance.html"
    
    def get(self, *args, **kwargs):
        p = self.request.GET.get("p", None)
        sideeffect_formset = SideeffectFormSet(queryset=SideEffect.objects.none(),)

        return self.render_to_response(
            { "sideeffect_formset": sideeffect_formset,
              "sideeffect_formsethelper": SideEffectFormSetSetHelper,
            }
        )

Для динамического изменения выбора поля в наборе форм необходимо определить пользовательский класс формы, который выполняет изменение выбора на __init__

from django import forms
from .models import SideEffect

class SideEffectForm(ModelForm):

    class Meta:
        model = SideEffect
        fields = ['se_name']

    def __init__(self, *args, p, **kwargs):
        super().__init__(*args, **kwargs)
        if p == 'foo':
            self.fields['se_name'].choices = [
                ("weight_gain", "Weight Gain"),
                ("parkinsonism", "Parkinsonism"),
            ]
        else:
            ...

Используйте класс формы в вашем наборе форм

SideeffectFormSet = inlineformset_factory(
    Case,
    SideEffect,
    form=SideEffectForm,
    extra=0,
    min_num=1,
    validate_min=True,
)

Затем в вашем представлении вы можете передать пользовательские параметры форме набора форм

sideeffect_formset = SideeffectFormSet(queryset=SideEffect.objects.none(), form_kwargs={'p': p})
Вернуться на верх