我在重写ModelForm保存方法时遇到问题.这是我收到的错误:

Exception Type:     TypeError  
Exception Value:    save() got an unexpected keyword argument 'commit'

我的目的是让表单提交3个字段的许多值,然后为这些字段的每个组合创建一个对象,并保存每个对象.有帮助地推动正确的方向将是王牌.

File 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)

File 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

File 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

the save method.

最后,这种模型形式中的很多都不起作用,这仅仅是因为您访问事物的方式.你需要使用self.fields['callResult']而不是self.callResult.

UPDATE:针对您的回答:

Aside:为什么不在模型中使用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, 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英镑,以防万一.

Django相关问答推荐

Django为不同应用程序发出信号

覆盖保存以创建范围的多个对象()

试图找出投票的总数,但无法理解它是如何在序列化器中完成的.我是Django的新手,它是如何完成的?

如何保护单个数据库行/模型实例?

情节主题更改问题

SQLite上可以正常使用Many2Many链接注释,但MariaDB上无法正常使用(生产环境)

Django: 无法将我的 comments 关联到特定产品

根据当前对象中的多对多字段过滤对象

Django 模型:如何查找自动生成的字段列表

如何将数据库中的 None 序列化为空对象?

无法通过 pip 安装 Django 2.0

无效的命令 WSGIDaemonProcess 在 CentOS 6.7 上部署 Django 应用程序

如何按名称设置 django 模型字段?

Django:如何使用动态(非模型)数据预填充 FormView?

Django manage.py:在其依赖之前应用迁移

django admin 排序外键字段列表

如何在 Django 中执行批量插入?

在 django 中获取空查询集的类名

Django:按位置排序,忽略 NULL

确保只有一个工作人员在运行多个工作人员的 pyramid 网络应用程序中启动 apscheduler 事件