当前位置: 首页 > 面试题库 >

覆盖Django ModelForm中的save方法

柴俊捷
2023-03-14
问题内容

我无法覆盖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

最后,由于你访问事物的方式,许多ModelForm都无法使用。相反self.callResult,你需要使用self.fields['callResult']

更新:针对你的回答:

旁:为什么不在ManyToManyField Model中使用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,以防万一。



 类似资料:
  • 在这个特定的示例中,我扩展了

  • 问题内容: 这个想法有些含糊不清,我需要澄清。 我的问题是使用此代码时: 输出为。 这是因为main函数与method在同一类中,还是由于重写? 我已经在书中读过这个想法,当我将该函数放在另一个类中时,会出现编译器错误。 问题答案: 您不能覆盖方法。如果投射到,则看不到。您 可以 覆盖一个方法,但这不是您要在此处执行的操作(是的,在这里,如果将移至,则会得到另一个方法。我建议您在打算覆盖时注解,

  • 问题内容: 在Java中重写私有方法是无效的,因为父类的私有方法是“自动最终的,并且对派生类是隐藏的”。我的问题主要是学术上的。 不允许父级的私有方法被“重写”(即,在子类中以相同的签名独立实现),这是否违反封装规范?根据封装的原理,子类不能访问或继承父级的私有方法。它是隐藏的。 那么,为什么应该限制子类实现自己的具有相同名称/签名的方法呢?这是否有一个良好的理论基础,还是仅仅是某种务实的解决方案

  • 问题内容: 是否可以在Python中覆盖+ =? 问题答案: 是的,重写该方法。例:

  • 问题内容: 因此,这是该书的引文: 覆盖方法不得抛出比被覆盖方法声明的异常新的或更广泛的检查异常。例如,声明FileNotFoundException的方法不能被声明SQLException,Exception或任何其他非运行时异常的方法覆盖,除非它是FileNotFoundException的子类。 现在这是我的问题,如果超类中的方法引发异常,那么重写方法可以根本不引发异常吗? 因为我只是在Ja

  • 问题内容: 有很多关于使用信号进行递归的Stack Overflow帖子,其中的注释和答案绝大多数是“为什么不重写save()”或仅在其上触发的保存。 好吧,我相信有一个不使用的好例子-例如,我正在添加一个临时应用程序,该应用程序处理与订单模型完全不同的订单履行数据。 框架的其余部分非常高兴地没有意识到实现应用程序,并且使用post_save挂钩将所有与实现相关的代码与我们的Order模型隔离开来