问题
I'm using django extra views:
# 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'
I want this 'keywords' field to change based on the pk I pass to the view through the url.
# forms.py
class LinkForm(forms.ModelForm):
keywords = forms.ModelMultipleChoiceField(queryset=ClientKeyword.objects.filter(client__pk=1))
class Meta:
model = Link
I could manage to overwrite the form's init, however:
I don't have access to self.kwargs inside LinkInline
Even if I did, I'm not sure I can pass an instantiated form to inlineformset_factory()
回答1:
Ok, if any poor soul needs an answer to how to accomplish this... I managed to do it by overwriting construct_inlines() (which is part of extra_views.advanced.ModelFormWithInlinesMixin) and modifying the field's queryset there.
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())
来源:https://stackoverflow.com/questions/14500795/how-can-i-change-the-queryset-of-one-of-the-fields-in-the-form-im-passing-to-in