覆盖Django ModelForm中的保存方法
我无法覆盖ModelForm
保存方法。 这是我收到的错误:
Exception Type: TypeError Exception Value: save() got an unexpected keyword argument 'commit'
我的意图是有一个表单提交3个字段的许多值,然后为这些字段的每个组合创build一个对象,并保存每个对象。 有用的推动是正确的方向将是王牌。
文件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']
。
更新 :回应你的答案:
另外:为什么不只是在模型中使用ManyToManyField
,所以你不必这样做? 好像你正在存储冗余数据并为自己(和我: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, ie 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
这允许inheritanceCallResultTypeForm
,以防万一需要。