将 kwarg 传递给 inlineformset_factory?

Pass kwarg into an inlineformset_factory?

我正在尝试将 request 对象传递到我的 inlineformset_factory 中,并且正在努力实现这一点。

forms.py 我有以下内容:

class SummativeScoreForm(forms.ModelForm):
    """
    Form definition for SummativeScore Form
    """

    subdomain_proficiency_level = forms.ModelChoiceField(
        empty_label="Undecided",
        queryset=SubdomainProficiencyLevel.objects.none(),
        widget=forms.RadioSelect,
        required=False,
    )

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request", None)
        super(SummativeScoreForm, self).__init__(*args, **kwargs)
        if self.instance:
            if self.request.user == self.instance.summative.employee:
                self.fields["subdomain_proficiency_level"].disabled = True
        self.fields[
            "subdomain_proficiency_level"
        ].queryset = SubdomainProficiencyLevel.objects.filter(
            subdomain=self.instance.subdomain
        )
        self.fields[
            "subdomain_proficiency_level"
        ].label = f"""
        {self.instance.subdomain.character_code}:
        {self.instance.subdomain.short_description}
        """

    class Meta:
        model = SummativeScore
        fields = "__all__"
        widgets = {
            "subdomain_proficiency_level": forms.RadioSelect(
                attrs={"class": "list-unstyled"}
            ),
        }


SummativeScoreInlineFormset = inlineformset_factory(
    Summative,
    SummativeScore,
    fields=("subdomain_proficiency_level",),
    can_delete=False,
    extra=0,
    form=SummativeScoreForm,
)

我正在使用 FormView CBV 来显示此 inline_formset

class SummativeScoreFormView(
    LoginRequiredMixin,
    UserIsObserverOrObserveeMixin,
    SingleObjectMixin,
    FormView,
):

    model = Summative
    template_name = "commonground/summative_score_form.html"
    pk_url_kwarg = "summative_id"

    def get(self, request, *args, **kwargs):
        summative_id = kwargs.pop("summative_id")
        self.object = self.get_object(
            queryset=Summative.objects.filter(id=summative_id)
        )
        return super().get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        summative_id = kwargs.pop("summative_id")
        self.object = self.get_object(
            queryset=Summative.objects.filter(id=summative_id)
        )
        return super().get(request, *args, **kwargs)

    def get_form(self, form_class=None):
        return SummativeScoreInlineFormset(
            **self.get_form_kwargs(), instance=self.object
        )

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs["request"] = self.request
        return kwargs

    def form_valid(self, form):
        form.save()
        messages.add_message(messages.SUCCESS, "Changes were saved!")
        HttpResponseRedirect(self.get_success_url())

    def form_invalid(self, form):
        print("invalid form")
        return super().form_invalid(form)

    def get_success_url(self):
        user_id = self.kwargs["user_id"]
        summative_id = self.kwargs["summative_id"]
        return reverse(
            "commonground:summative_detail",
            kwargs={
                "user_id": user_id,
                "summative_id": summative_id,
            },
        )

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        summative = get_object_or_404(
            Summative, pk=self.kwargs["summative_id"]
        )
        context["summative"] = summative
        return context

我不断收到此错误:

__init__() got an unexpected keyword argument 'request'

我不确定如何最好地解决这个问题 - 有什么想法吗?有没有明确的方法将 request 传递给 inlineformset_factory

您正在将请求传递给表单集,而不是表单集中的表单,因此出现错误。对于 passing custom parameters to the formsets forms [Django docs],您需要将 form_kwargs 参数传递给表单集:

class SummativeScoreFormView(
    LoginRequiredMixin,
    UserIsObserverOrObserveeMixin,
    SingleObjectMixin,
    FormView,
):
    ...
    
    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['form_kwargs'] = {'request': self.request}
        return kwargs