Ich habe Probleme, eine Speichermethode von ModelForm
zu überschreiben. Dies ist der Fehler, den ich erhalte:
Exception Type: TypeError
Exception Value: save() got an unexpected keyword argument 'commit'
Ich beabsichtige, in einem Formular viele Werte für drei Felder einzureichen, dann für jede Kombination dieser Felder ein Objekt zu erstellen und jedes dieser Objekte zu speichern. Hilfreiche Stupser in die richtige Richtung wären Ass.
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
In Ihrem save
muss das Argument commit
stehen. Wenn etwas Ihr Formular überschreibt oder ändern möchte, was gespeichert wird, wird save(commit=False)
ausgeführt, die Ausgabe geändert und dann selbst gespeichert.
Außerdem sollte Ihre ModelForm das Modell zurückgeben, das sie speichert. Normalerweise sieht das save
einer ModelForm ungefähr so aus:
def save(self, commit=True):
m = super(CallResultTypeForm, self).save(commit=False)
# do custom stuff
if commit:
m.save()
return m
Lesen Sie weiter die save
Methode .
Letztendlich wird ein Großteil dieser ModelForm nicht funktionieren, nur weil Sie auf bestimmte Dinge zugreifen. Anstelle von self.callResult
Müssen Sie self.fields['callResult']
Verwenden.
[~ # ~] Update [~ # ~] : Als Antwort auf Ihre Antwort:
Nebenbei: Warum nicht einfach ManyToManyField
s im Modell verwenden, damit Sie dies nicht tun müssen? Scheint, als würden Sie redundante Daten speichern und mehr Arbeit für sich selbst (und mich :P
) Erledigen.
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
Dies ermöglicht die Vererbung von CallResultTypeForm
, für den Fall, dass dies jemals notwendig ist.