假设我有一组记录,根据其他记录和电子邮件,我知道这些记录是唯一的:
class Signup(models.Model):
activity = models.ForeignKey(Activity, related_name='activities')
name = models.CharField(max_length=100)
email = models.EmailField()
# many addtional fields here not relevant to question
然后,我有一个模型表单:
class SignupForm(forms.ModelForm):
class Meta:
model = Signup
exclude = [ 'activity' ]
def __init__(self, *args, **kwargs):
self.activity = kwargs.pop('activity')
def save(self, *args, **kwargs):
kwargs['commit'] = False
m = super(SignupForm, self).save(*args, **kwargs)
m.activity = self.activity
m.save()
return m
假设用户填写活动下的表单,然后意识到他们在表单中出错,点击后退按钮,进行更改,然后再次点击提交。
如果不对上述代码进行任何修改,将会创建该活动和电子邮件的重复记录。
我想知道的是,如果找到与输入的电子邮件匹配的记录,我可以强制表单更新而不是创建记录。
我试过这段代码:
class SignupForm(forms.ModelForm):
class Meta:
model = Signup
exclude = [ 'activity' ]
def __init__(self, *args, **kwargs):
self.activity = kwargs.pop('activity')
def save(self, *args, **kwargs):
kwargs['commit'] = False
try:
self.instance = Signup.objects.get(email=self.cleaned_data['email'], activity=self.activity)
except Signup.DoesNotExist:
pass
m = super(SignupForm, self).save(*args, **kwargs)
m.activity = self.activity
m.save()
return m
然而,看起来这样会导致表单由于某种原因忽略所有新信息(我debug toolbar正在运行并检查查询确认没有任何字段被更改!)
是否有可接受的处理方式?
有没有办法在使用ModelForm
的内置save
功能时执行此操作?到目前为止,答案似乎表明这是不可能的,也就是说,我很抱歉,这很荒谬。
答案 0 :(得分:1)
替换
try:
self.instance = Signup.objects.get(email=self.cleaned_data['email'], activity=self.activity)
except Signup.DoesNotExist:
pass
使用:
obj, created = Signup.objects.get_or_create(\
email=self.cleaned_data['email'],
activity=self.activity)
if created:
print 'its a new one, hooray!'
else:
print 'the object exists!'
有关get_or_create
的更多信息。