我试图在前一个问题(django crispy forms: Nesting a formset within a form)中遵循@qris给出的答案,但我在渲染函数中的formset = context[self.formset_name_in_context]
处得到了一个KeyError。我不太明白发生了什么。背景来自哪里?我该如何解决这个问题?
在forms.py中,我为AuthorForm创建了一个formset:
AuthorFormSet = formset_factory(AuthorForm)
author_formset = AuthorFormSet()
然后我在其他表单的布局中使用author_formset
:
self.helper.layout = Layout(
Div(
Div('place', 'sample', css_class='col-xs-6'),
Div('subject_type', 'data_title', css_class='col-xs-6'),
css_class='row'
),
MultiField(
"Authors",
Formset('author_formset'),
)
)
我在views.py中的最新尝试:
class register(TemplateView):
form_class = RegistrationForm()
facility_form = FacilityAndContactForm()
formsets = {
'author_formset': AuthorFormSet,
}
template_name = "databank/depositors.html"
def __init__(self, data, files, *args, **kwargs):
super(register, self).__init__(data, files, *args, **kwargs)
if 'initial' in kwargs:
# Formsets treat this parameter completely differently: they
# expect an array of values instead of just one. So remove it
# because it will break formsets.
kwargs.pop('initial')
for name, formset_class in self.formsets.iteritems():
# doesn't exist yet, so we can't call its queryset() method
queryset = formset_class.model._default_manager.filter(
**{formset_class.fk.name: self.instance})
extra = 0 if queryset.exists() else 1
formset = self.construct_formset(formset_class, data, files, *args, prefix=name, extra=extra, **kwargs)
setattr(self, name, formset)
helper = getattr(formset.form(), 'helper', None)
if helper:
formset.helper = helper
def construct_formset(self, formset_class, data, files, prefix, extra,
*args, **kwargs):
return formset_class(data, files, *args, prefix=prefix, extra=extra,
**kwargs)
def get(self, request, *args, **kwargs):
form_class = self.form_class
return render(request, self.template_name, {'form_class': form_class,
'facility_form': self.facility_form, 'author_formset':
self.formset})
def post(self, request):
form_class = RegistrationForm(request.POST, request.FILES)
facility_form = FacilityAndContactForm(request.POST)
author_formset=AuthorFormSet(request.POST)
formsets = {
'author_formset': author_formset,
}
if form_class.is_valid():
registration = create_registration(form_class)
dataset_name = registration.dataset.dataset_name
# more logic here...
return render(request, 'databank/register.html',
{'registration_form': form_class, 'facility_form': facility_form,
'author_formset': author_formset})
答案 0 :(得分:1)
你必须自己把author_formset放到上下文中:)它无法通过任何其他方式实现。
这就是我自己概括的方法,在我的表格上有一个dict
自动构建的子formsets
:
class MyForm(ModelForm):
formsets = {
'author_formset': AuthorFormSet,
}
def __init__(self, data, files, *args, **kwargs):
super(MyView, self).__init__(data, files, *args, **kwargs)
if 'initial' in kwargs:
# Formsets treat this parameter completely differently: they
# expect an array of values instead of just one. So remove it
# because it will break formsets.
kwargs.pop('initial')
for name, formset_class in self.formsets.iteritems():
# doesn't exist yet, so we can't call its queryset() method
queryset = formset_class.model._default_manager.filter(
**{formset_class.fk.name: self.instance})
extra = 0 if queryset.exists() else 1
formset = self.construct_formset(formset_class, data, files, *args,
prefix=name, extra=extra, **kwargs)
setattr(self, name, formset)
helper = getattr(formset.form(), 'helper', None)
if helper:
formset.helper = helper
def construct_formset(self, formset_class, data, files, prefix, extra,
*args, **kwargs):
return formset_class(data, files, *args, prefix=prefix, extra=extra,
**kwargs)