我有一個可以有一個或多個模型的系統。我已經在數據庫中建立了一個多元關係的關係模型。下面的代碼用於以單一形式編輯系統及其相關方法。Django modelformset創建新記錄而不是更新現有的記錄
填寫其形式和緊迫只提交第一次作品添加新方法。如果我那麼做一個小的變化,然後再次提交,我得到以下信息(由下面的代碼生成):
METHODFORMSET.ERRORS: [{}, {'name': [u'Method with this Name already exists.']}]
這是一個事實,即名稱字段是唯一引起的,但它應該有更新,不創建一個新的紀錄,即使我使用POST數據生成methodformset實例...
請注意這種行爲只適用於最後一個附加方法的實例,而不是那些已經存在在桌子裏。
這裏是相關的代碼,任何人都可以讓我知道我在做什麼錯了嗎?
def sysedit(request, sys_id):
system = System.objects.get(id=sys_id)
MethodFormSet = modelformset_factory(Method, form=MethodForm)
post = None
if request.POST:
post = request.POST.copy()
if 'add_method' in request.POST:
post['method-TOTAL_FORMS'] = repr(int(
post['method-TOTAL_FORMS'])+ 1)
systemform = SystemForm(data=post, instance=system)
methodformset = MethodFormSet(data=post, prefix='method',
queryset=Method.objects.filter(id__in=system.method.all()))
if methodformset.is_valid():
mfs = methodformset.save()
print 'SAVED-method', mfs
for mf in mfs:
if systemform.is_valid():
sp = systemform.save(mf)
print 'SYSTEM', sp
else:
print 'SYSFORMSET.ERRORS:', systemform.errors
else:
print 'METHODFORMSET.ERRORS:', methodformset.errors
return render_to_response('sysedit.html',
{'systemform': systemform,
'methodformset': methodformset,
'system': system},
context_instance=RequestContext(request))
class System(models.Model):
method = models.ManyToManyField(Method)
...
class Method(models.Model):
name = models.CharField(unique=True)
...
class MethodForm(ModelForm):
class Meta:
model = Method
class SystemForm(ModelForm):
def save(self, new_method=None, commit=True, *args, **kwargs):
m = super(SystemForm, self).save(commit=False, *args, **kwargs)
if new_method:
m.method.add(new_method)
if commit:
m.save()
return m
class Meta:
model = System
exclude = ('method')
[後Sergzach的回答編輯]:
的問題不在於如何應對Method with this name already exists
錯誤,但要防止來自於未然。我認爲實際問題可能與模型表單處理新表單的方式有關。不管怎樣,它看起來總是試圖爲最後一個formset創建一個新實例,而不管它是否已經退出。
所以如果我在最後一個被追加後沒有添加新的表單集,那麼modelformset會嘗試重新創建最後一個表單(儘管它剛剛在前一個提交中創建)。
最初的情況是,我在methodformset中有1個有效的Method實例和1個新的未綁定實例。然後我填寫表單並點擊保存,這將驗證兩個方法並綁定第二個,然後將其保存到表中。 到目前爲止一切都很順利,但如果我再次點擊保存第二次錯誤發生。也許這與方法-TOTAL_FORMS = 2和method-INITIAL_FORMS = 1這一事實有關。這是否會導致modelformset在第二個方法上強制創建?
任何人都可以確認/否認這一點?
[不看代碼一個週末後編輯]:
的問題是由我保存在視圖中,並保存後的形式造成的事實,我送原methodformset實例(從前保存)到模板。該問題可以通過使用queryset而不是POST數據在保存之後重新實例化modelformset 來解決。
因此,防止這樣的錯誤的一般規則是在保存之後轉到不同的頁面(完全避免它)或使用上述解決方案。
在我發佈這個解決方案之前,我需要做更多的測試。
OK保存(在這個問題的底部看到編輯)後解決了這個問題,我看到我的答案是不是你的問題。我會審查它。 – sergzach 2012-07-27 10:57:06
原理是相似的,並且需要更復雜的代碼,因爲我們與模型表單有交易,但與表單無關。 – sergzach 2012-07-27 11:16:21
我改變了我的答案。請查看。 – sergzach 2012-07-27 19:53:03