2011-05-28 64 views
4

我正在試圖製作一個允許用戶編輯模型實例(本例中爲事件)的視圖。不幸的是,提交這個表單會創建一個新的實例(帶有一個新的ID),甚至不會刪除舊的實例。我的印象是,保存方法,被認爲在這種情況下,以更新實例下...使用ModelForm編輯模型實例會創建新的實例而不是更新

注:EventForm是的ModelForm

我使用每https://docs.djangoproject.com/en/dev/ref/models/instances/#forcing-an-insert-or-update的force_update ARG嘗試過,但沒有骰子。我也嘗試刪除form.is_valid()區塊中的原始事件(通過調用event.delete()),但是......沒有骰子。

我有一種感覺,commit=False是問題嗎?我不確定!

謝謝。

(請忽略代碼段間距問題)

def edit_event(request, event_id): 
event = Event.objects.get(pk=event_id) 

if request.method == 'POST': 
    post_data = request.POST.copy() 

    # here is some validation that can't be done in the ModelForm... 

    #form = EventForm(post_data, request.FILES, instance=event) 
    form = EventForm(post_data, request.FILES) 

    if form.is_valid(): 

     edited_event = form.save(commit=False) 

     edited_event.save(force_update=True) # doesn't work with or without force_update arg 

     #form.save_m2m() # needed for ManyToMany relationship 

     return HttpResponseRedirect('/events/view/%s' % edited_event.id) 
    else: 
     form = EventForm(instance=event) 

return render_to_response('create_event.html', {'form': form,}, context_instance=RequestContext(request)) 

UPDATE

我擺脫我的模型M2M的關係,所以我能夠擺脫form.save_m2m()線。這仍然行不通。

我也試過在提交表單時沒有通過實例,假設當用戶提交時(現在是這種情況)正確的字段將被預先填充。這仍然不起作用。

我錯過了一個重要的細節,當涉及到更新模型?

回答

2

從我所能理解的,你的代碼的問題是,你總是在保存之前創建一個新的實例。由於您已經在「event = Event.objects.get(pk = event_id)」中獲得了該事件的實例,因此您可以簡單地更改此實例並將其保存起來,並且我確信會導致django創建一個更新。

我勸你看看這個鏈接: https://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs#how-django-knows-to-update-vs-insert

這對算法Django使用的插入和更新來區分一個相當簡單的解釋。如果你的對象沒有它的主鍵集(可能是你在syncdb時django自動創建的「id」字段),那麼它將被視爲一個新的對象。如果它設置了該字段,那麼Django將嘗試在數據庫中查找該特定記錄,如果它存在,它將被更新。

希望答案很清楚。

-3

你的例子太複雜了。嘗試從簡單的模型/視圖/表單開始。用一個簡單的字段創建新模型,然後創建模型表單和視圖並確保它們可以工作。然後開始修改視圖以使其更接近實際狀態。

+0

?你的推理是什麼,我的例子太複雜了?在我看到的Django文檔中沒有任何地方說過... – jakecar 2011-05-28 16:09:42

5

我想你應該像這樣初始化表單(因爲你已經註釋掉了)。

form = EventForm(post_data, request.FILES, instance=event) 

然後事件對象與以下形式相關聯,並且可以form.save()代替執行插入的更新。

0

資料中顯示和更新工作代碼:

@login_required(login_url=LOGIN_URL) 
@csrf_exempt 
def profile(request): 
    """ 
    :param request: 
    :param: 
    :return: 
    """ 
    val = get_object_or_404(Profil, user=request.user) 

if request.method == 'POST': 
    form = ProfilForm(request.POST, request.FILES, instance=val) 
    if form.is_valid(): 
     form.save() 
     msg_ok = u'Profil updated' 
    else: 
     msg_err = u"Invalid form." 
else: 
    form = ProfilForm(instance=val) 

return render(request, "back/profile.html", locals()) 
相關問題