更新:エラーが見つかりました...
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)
上記の部分により、フォームが保存されなくなりました。理由はわかりません。これを削除し、比較的ハックな回避策を実行すると、修正されました。これで、JavaScript を使用して入力されたフォームにModelSelect という名前が付けられcompany
ました。
元の質問:
基本的にフォームセットのみを表示および保存するDjangoビューがあります。そのコードは次のとおりです。
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))
これの目的は、ユーザーがデータベースから契約者を作成/更新/削除できるようにすることです。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)
問題は、何らかの理由で元の担当者のみがデータベースに保存されることです。新しい担当者の save() メソッドが呼び出されることはないため、新しい担当者が作成されることはありません。私が見る限り、すべてのデータは POST にあります。元のアイテムは 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'']}