class BaseContactPersonFormSet(forms.models.BaseModelFormSet):
def __init__(self, company, data=None, **kwargs):
super(BaseContactPersonFormSet, self).__init__(**kwargs)
for form in self:
form.company = company
ContactPersonFormSet = forms.models.modelformset_factory(model=Person, form=SingleContactPersonForm, formset=BaseContactPersonFormSet, can_delete=True, extra=0)
上面的部分导致表格永不保存,我不知道为什么。删除它并做一个相对hacky的解决方法为我修复它。现在我在表单中有一个名为company
的ModelSelect,它使用JavaScript填充。
我有一个Django视图,基本上只显示和保存一个formset,代码是:
def manage_company_contact_persons(request, company_id):
company = get_object_or_404(Company, id=company_id)
if request.method == 'POST':
print request.POST
cpfs = forms.ContactPersonFormSet(queryset=company.contact_persons.all(), data=request.POST)
if cpfs.is_valid():
for cpf in cpfs:
print cpf.errors
cpf.save()
else:
cpfs = forms.ContactPersonFormSet(queryset=company.contact_persons.all())
return render_to_response('company/manage/admin-crm-company-contactpersons-new.html',
{'contactpersons': cpfs,
'company': company,},
context_instance=RequestContext(request))
这样做的目的是允许用户从数据库中创建/更新/删除Contractpersons。 ContactPersonFormSet定义如下:
class SingleContactPersonForm(forms.ModelForm):
# Fields for the User model
first_name = forms.CharField(widget=forms.TextInput(attrs={'class': 'w170'}), required=True, label=_(u'First name'))
last_name = forms.CharField(widget=forms.TextInput(attrs={'class': 'w170'}), required=True, label=_(u'Last name'))
email = forms.EmailField(widget=forms.TextInput(attrs={'class': 'w170'}), required=True, label=_(u'E-Mail'))
password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'w170'}), required=False, label=_(u'Password'))
# Fields for the Address model
zip_code = forms.CharField(widget=forms.TextInput(attrs={'class': 'w100 address'}), required=False, label=_(u'Zip code + house number'))
house_number = forms.CharField(widget=forms.TextInput(attrs={'class': 'w60 address'}), required=False, label=_(u'Zip code + house number'))
street = forms.CharField(widget=forms.TextInput(attrs={'class': 'w170 address'}), required=False, label=_(u'Street'))
city = forms.CharField(widget=forms.TextInput(attrs={'class': 'w170 address'}), required=False, label=_(u'City'))
country = forms.ModelChoiceField(queryset=Country.objects.all(), widget=forms.Select(attrs={'class address': 'w170'}), required=False, label=_(u'Country'))
def __init__(self, *args, **kwargs):
super(SingleContactPersonForm, self).__init__(*args, **kwargs)
### If there is an instance, get it to fill extra fields
def save(self, commit=True, *args, **kwargs):
'''Saves the whole contact Person to the database, including the address and the user.'''
super(SingleContactPersonForm, self).save(*args, commit=commit, **kwargs)
### save data in other models
if commit:
super(SingleContactPersonForm, self).save()
return self
class Meta:
model = Person
fields = ['job_title', 'telephone_number', 'mobile_number', 'fax']
widgets = {'job_title': forms.TextInput(attrs={'class': 'w170'}),
'telephone_number': forms.TextInput(attrs={'class': 'w170'}),
'mobile_number': forms.TextInput(attrs={'class': 'w170'}),
'fax': forms.TextInput(attrs={'class': 'w170'}),
}
ContactPersonFormSet = forms.models.modelformset_factory(model=Person, form=SingleContactPersonForm, can_delete=True, extra=0)
问题在于,由于某种原因,只有原始联系人才会保存到数据库中。永远不会创建新的联系人,因为永远不会调用新的联系人。据我所见,所有数据都在POST中。 formset也是有效的,因为原始项确实调用了save()函数。
是否可能会因为我在POST数据中包含一个空的“id”而失败?
POST中的数据是:
{u'csrfmiddlewaretoken': [u'056d5042e73322c8166011e27108d362'],
u'form-0-city': [u'Culemborg'],
u'form-0-country': [u'155'],
u'form-0-email': [u'info@domain1.com'],
u'form-0-fax': [u'0345750249'],
u'form-0-first_name': [First'],
u'form-0-house_number': [u'7'],
u'form-0-id': [u'69'],
u'form-0-job_title': [u'Job'],
u'form-0-last_name': [u'Name'],
u'form-0-mobile_number': [u''],
u'form-0-password': [u''],
u'form-0-street': [u'Street'],
u'form-0-telephone_number': [u'0123456789'],
u'form-0-zip_code': [u'4104AN'],
u'form-1-city': [u'Culemborg'],
u'form-1-country': [u'155'],
u'form-1-email': [u'info@domain2.com'],
u'form-1-fax': [u''],
u'form-1-first_name': [u'Second'],
u'form-1-house_number': [u'7'],
u'form-1-id': [u''],
u'form-1-job_title': [u'Function'],
u'form-1-last_name': [u'Name'],
u'form-1-mobile_number': [u''],
u'form-1-password': [u''],
u'form-1-street': [u'Nijverheidsweg'],
u'form-1-telephone_number': [u'0987654321'],
u'form-1-zip_code': [u'4104AN'],
u'form-INITIAL_FORMS': [u'1'],
u'form-MAX_NUM_FORMS': [u'1000'],
u'form-TOTAL_FORMS': [u'1'],
u'form-__prefix__-city': [u''],
u'form-__prefix__-country': [u''],
u'form-__prefix__-email': [u''],
u'form-__prefix__-fax': [u''],
u'form-__prefix__-first_name': [u''],
u'form-__prefix__-house_number': [u''],
u'form-__prefix__-id': [u''],
u'form-__prefix__-job_title': [u''],
u'form-__prefix__-last_name': [u''],
u'form-__prefix__-mobile_number': [u''],
u'form-__prefix__-password': [u''],
u'form-__prefix__-street': [u''],
u'form-__prefix__-telephone_number': [u''],
u'form-__prefix__-zip_code': [u'']}
答案 0 :(得分:1)
修改强>
我想我发现了你的错误。你忘了将“数据”arg传递给那个“超级”电话。你写了这个:
class BaseContactPersonFormSet(forms.models.BaseModelFormSet):
def __init__(self, company, data=None, **kwargs):
super(BaseContactPersonFormSet, self).__init__(**kwargs)
for form in self:
form.company = company
ContactPersonFormSet = forms.models.modelformset_factory(model=Person, form=SingleContactPersonForm, formset=BaseContactPersonFormSet, can_delete=True, extra=0)
但你应该这样写:
class BaseContactPersonFormSet(forms.models.BaseModelFormSet):
def __init__(self, company, data=None, **kwargs):
super(BaseContactPersonFormSet, self).__init__(data, **kwargs)
for form in self:
form.company = company
ContactPersonFormSet = forms.models.modelformset_factory(model=Person, form=SingleContactPersonForm, formset=BaseContactPersonFormSet, can_delete=True, extra=0)
OLD ANSWER:
尝试更改这些行:
if cpfs.is_valid():
for cpf in cpfs:
print cpf.errors
cpf.save()
这些行:
if cpfs.is_valid():
cpfs.save()
取自here