Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Django ModelForm中重写save方法_Python_Django_Django Forms_Django Admin - Fatal编程技术网

Python 在Django ModelForm中重写save方法

Python 在Django ModelForm中重写save方法,python,django,django-forms,django-admin,Python,Django,Django Forms,Django Admin,重写ModelFormsave方法时遇到问题。这是我收到的错误: Exception Type: TypeError Exception Value: save() got an unexpected keyword argument 'commit' 我的意图是让表单为3个字段提交多个值,然后为这些字段的每个组合创建一个对象,并保存每个对象。在正确的方向上有助于推动将是ace 文件models.py 文件forms.py 文件admin.py 在save中,必须有参数com

重写
ModelForm
save方法时遇到问题。这是我收到的错误:

Exception Type:     TypeError  
Exception Value:    save() got an unexpected keyword argument 'commit'
我的意图是让表单为3个字段提交多个值,然后为这些字段的每个组合创建一个对象,并保存每个对象。在正确的方向上有助于推动将是ace

文件
models.py
文件
forms.py
文件
admin.py

save
中,必须有参数
commit
。如果有任何内容覆盖了您的表单,或者想要修改它保存的内容,它将执行
save(commit=False)
,修改输出,然后保存它自己

此外,您的模型表单应该返回它保存的模型。通常,模型表单的
保存
将类似于:

def save(self, commit=True):
    m = super(CallResultTypeForm, self).save(commit=False)
    # do custom stuff
    if commit:
        m.save()
    return m
仔细阅读

最后,由于您访问事物的方式,这种模型形式中的很多都无法工作。您需要使用
self.fields['callResult']
,而不是
self.callResult

更新:针对您的回答:

旁白:为什么不在模型中使用
ManyToManyField
s,这样您就不必这样做了?似乎您正在存储冗余数据并为自己(和我
:P
)做更多的工作


这允许继承
CallResultTypeForm
,以备不时之需。

为了澄清,您想为每个callType、每个callResult、每个活动保存一个CallResultType吗?我不使用多对多字段,因为我需要映射表上的额外数据,因此,我需要遍历一个表并在中间表上创建数据。我认为我无法在管理应用程序中创建所需的行为。当我试图查看对象时,会抛出一个错误,因为模型字段是外键,不是多对多关系。顺便说一句,您不应该忘记将
*args
**kwargs
参数添加到
save
方法中。对于现在使用此方法的任何人(目前为Django 1.10),现在只有
commit=True
参数——它没有
force\u insert
force\u update
参数。
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
class CallResultTypeAdmin(admin.ModelAdmin):
    form = CallResultTypeForm
def save(self, commit=True):
    m = super(CallResultTypeForm, self).save(commit=False)
    # do custom stuff
    if commit:
        m.save()
    return m
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