ModelForm
saveメソッドのオーバーライドに問題があります。これは私が受け取っているエラーです:
Exception Type: TypeError
Exception Value: save() got an unexpected keyword argument 'commit'
私の意図は、フォームに3つのフィールドの多くの値を送信させ、それらのフィールドの組み合わせごとにオブジェクトを作成し、それらの各オブジェクトを保存することです。正しい方向に役立つナッジはエースでしょう。
models.py
class CallResultType(models.Model):
id = models.AutoField(db_column='icontact_result_code_type_id', primary_key=True)
callResult = models.ForeignKey('CallResult', db_column='icontact_result_code_id')
campaign = models.ForeignKey('Campaign', db_column='icampaign_id')
callType = models.ForeignKey('CallType', db_column='icall_type_id')
agent = models.BooleanField(db_column='bagent', default=True)
teamLeader = models.BooleanField(db_column='bTeamLeader', default=True)
active = models.BooleanField(db_column='bactive', default=True)
forms.py
from Django.forms import ModelForm, ModelMultipleChoiceField
from callresults.models import *
class CallResultTypeForm(ModelForm):
callResult = ModelMultipleChoiceField(queryset=CallResult.objects.all())
campaign = ModelMultipleChoiceField(queryset=Campaign.objects.all())
callType = ModelMultipleChoiceField(queryset=CallType.objects.all())
def save(self, force_insert=False, force_update=False):
for cr in self.callResult:
for c in self.campain:
for ct in self.callType:
m = CallResultType(self) # this line is probably wrong
m.callResult = cr
m.campaign = c
m.calltype = ct
m.save()
class Meta:
model = CallResultType
admin.py
class CallResultTypeAdmin(admin.ModelAdmin):
form = CallResultTypeForm
save
には、引数commit
が必要です。フォームを上書きしたり、保存内容を変更したい場合は、save(commit=False)
を実行し、出力を変更してから、それ自体を保存します。
また、ModelFormは保存しているモデルを返す必要があります。通常、ModelFormのsave
は次のようになります。
def save(self, commit=True):
m = super(CallResultTypeForm, self).save(commit=False)
# do custom stuff
if commit:
m.save()
return m
save
メソッド を参照してください。
最後に、このModelFormの多くは、物にアクセスする方法が理由で機能しません。 self.callResult
の代わりに、self.fields['callResult']
を使用する必要があります。
[〜#〜] update [〜#〜]:回答に応じて:
脇:なぜモデルでManyToManyField
sを使用しないので、これを行う必要はありませんか?冗長なデータを保存し、自分自身のためにもっと仕事をしているようです(私は:P
)。
from Django.db.models import AutoField
def copy_model_instance(obj):
"""
Create a copy of a model instance.
M2M relationships are currently not handled, i.e. they are not copied. (Fortunately, you don't have any in this case)
See also Django #4027. From http://blog.elsdoerfer.name/2008/09/09/making-a-copy-of-a-model-instance/
"""
initial = dict([(f.name, getattr(obj, f.name)) for f in obj._meta.fields if not isinstance(f, AutoField) and not f in obj._meta.parents.values()])
return obj.__class__(**initial)
class CallResultTypeForm(ModelForm):
callResult = ModelMultipleChoiceField(queryset=CallResult.objects.all())
campaign = ModelMultipleChoiceField(queryset=Campaign.objects.all())
callType = ModelMultipleChoiceField(queryset=CallType.objects.all())
def save(self, commit=True, *args, **kwargs):
m = super(CallResultTypeForm, self).save(commit=False, *args, **kwargs)
results = []
for cr in self.callResult:
for c in self.campain:
for ct in self.callType:
m_new = copy_model_instance(m)
m_new.callResult = cr
m_new.campaign = c
m_new.calltype = ct
if commit:
m_new.save()
results.append(m_new)
return results
これにより、必要に応じてCallResultTypeForm
の継承が可能になります。