python - radioselect - select django
Anulando el método guardar en Django ModelForm (1)
Tengo problemas para anular un método de guardado de ModelForm
. Este es el error que estoy recibiendo:
Exception Type: TypeError
Exception Value: save() got an unexpected keyword argument ''commit''
Mis intenciones son hacer que un formulario envíe muchos valores para 3 campos, luego crear un objeto para cada combinación de esos campos y guardar cada uno de esos objetos. Un codazo útil en la dirección correcta sería ace.
Archivo 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)
Archivo 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
Archivo admin.py
class CallResultTypeAdmin(admin.ModelAdmin):
form = CallResultTypeForm
En tu save
debes tener el argumento commit
. Si algo sobrescribe su formulario, o quiere modificar lo que está guardando, lo hará save(commit=False)
, modificar el resultado, y luego guardarlo.
Además, su ModelForm debe devolver el modelo que está guardando. Por lo general, el guardado de un ModelForm se verá algo así como:
def save(self, commit=True):
m = super(CallResultTypeForm, self).save(commit=False)
# do custom stuff
if commit:
m.save()
return m
Lea sobre el método de save
.
Finalmente, mucho de este ModelForm no funcionará solo por la forma en que está accediendo a las cosas. En lugar de self.callResult
, necesita usar self.fields[''callResult'']
.
ACTUALIZACIÓN : En respuesta a su respuesta:
Aparte: ¿por qué no usar ManyToManyField
s en el Modelo para que no tenga que hacer esto? Parece que está almacenando datos redundantes y haciendo más trabajo para usted (y para mí :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
Esto permite la herencia de CallResultTypeForm
, en caso de que sea necesario.