Переопределение метода save в Django ModelForm
у меня возникли проблемы с переопределением a 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
1 ответ:
в своем
saveвы должны иметь аргументcommit. Если что-то переопределяет вашу форму или хочет изменить то, что она сохраняет, она будет делатьsave(commit=False), измените вывод, а затем сохраните его сам.кроме того, ваша модель должна возвращать модель, которую она сохраняет. Обычно 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метод.наконец, многие из этой модели не будут работать только из-за как вы получаете доступ к вещам. Вместо
self.callResult, вы должны использоватьself.fields['callResult'].обновление: в ответ на ваш ответ:
в сторону: почему бы просто не использовать
ManyToManyFields в модели, так что вам не нужно этого делать? Похоже, вы храните избыточные данные и делаете больше работы для себя (и меня: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, только в случае необходимости.
Comments