Django 如何更改I'形式的其中一个字段的查询集;我要去inlineformset\u工厂

Django 如何更改I'形式的其中一个字段的查询集;我要去inlineformset\u工厂,django,django-views,inline-formset,Django,Django Views,Inline Formset,我使用的是django额外视图: # views.py from django.forms.models import inlineformset_factory from extra_views import (CreateWithInlinesView, UpdateWithInlinesView, InlineFormSet, ) class LinkInline(InlineFormSet): model = Link f

我使用的是django额外视图:

# views.py
from django.forms.models import inlineformset_factory
from extra_views import (CreateWithInlinesView, UpdateWithInlinesView,
                        InlineFormSet, )

class LinkInline(InlineFormSet):
    model = Link
    form = LinkForm
    extra = 1

    def get_form(self):
        return LinkForm({})

    def get_formset(self):
        return inlineformset_factory(self.model, self.get_inline_model(), form=LinkForm, **self.get_factory_kwargs())

class TargetCreateView(BaseSingleClient, CreateWithInlinesView):
    model = Target
    form_class = TargetForm
    inlines = [LinkInline, ]
    template_name = 'clients/target_form.html'
我希望此“关键字”字段根据我通过url传递给视图的主键进行更改

# forms.py
class LinkForm(forms.ModelForm):
    keywords = forms.ModelMultipleChoiceField(queryset=ClientKeyword.objects.filter(client__pk=1))

    class Meta:
        model = Link
我可以设法覆盖表单的init,但是:

  • 我无法访问LinkInline中的self.kwargs

  • 即使我这样做了,我也不确定是否可以将实例化的表单传递给inlineformset_factory()


  • 好吧,如果任何一个可怜的灵魂需要一个如何实现这一点的答案。。。我通过覆盖construct_inlines()(它是extra_views.advanced.ModelFormWithInlinesMixin的一部分)并修改字段的查询集来实现这一点

    class TargetCreateView(BaseSingleClient, CreateWithInlinesView):
        model = Target
        form_class = TargetForm
        inlines = [LinkInline, ]
        template_name = 'clients/target_form.html'
    
        def construct_inlines(self):
            '''I need to overwrite this method in order to change
            the queryset for the "keywords" field'''
            inline_formsets = super(TargetCreateView, self).construct_inlines()
            inline_formsets[0].forms[0].fields[
                    'keywords'].queryset = ClientKeyword.objects.filter(
                            client__pk=self.kwargs['pk'])
            return inline_formsets
    
        def forms_valid(self, form, inlines):
            context_data = self.get_context_data()
            # We need the client instance
            client = context_data['client_obj']
            # And the cleaned_data from the form
            data = form.cleaned_data
            self.object = self.model(
                    client=client,
                    budget=data['budget'],
                    month=data['month']
            )
            self.object.save()
            for formset in inlines:
                f_cd = formset.cleaned_data[0]
                print self.object.pk
                link = Link(client=client,
                        target=self.object,
                        link_type=f_cd['link_type'],
                        month=self.object.month,
                        status='PEN',
                )
                # save the object so we can add the M2M fields
                link.save()
                for kw in f_cd['keywords'].all():
                    link.keywords.add(kw)
            return HttpResponseRedirect(self.get_success_url())
    

    既然你提前有了pk,你有没有考虑过用咖喱将pk传递到表单中?我在答案中添加了我如何做到这一点的代码,但我很感兴趣。。。甚至不知道什么是curry当我需要将一个值传递给我在表单集中使用的表单时,我使用curry:
    来自django.utils.functional import curry
    MyFormset.form=staticmethod(curry(MyForm,pk=pk))。在本例中,表单需要接受
    pk
    的kwarg。噢,。。。类似这样的内容:。问题是我只能从TargetCreateView中获取pk。如果我在LinkInline中有它,我可能能够从get\u formset()返回
    inlineformset\u工厂(self.model,self.get\u inline\u model(),form=curry(LinkForm,pk=pk),**self.get\u工厂\u kwargs())
    ,但由于它不在那里,我不知道它将如何工作,额外的视图内置了curry技巧(见以下几行:),所以问题很简单,视图kwargs没有被传递到内联,这应该是相对简单的介绍。我只需要确保没有严重的向后兼容性问题。我也可以传递视图对象,这样您就不必重做已经在视图中处理过的任何工作。