2011-04-15 50 views
0

我有一個是基於以下模型中的ModelForm字段:Instanting的ModelForm與在modelfields被覆蓋

class Phrase(models.Model): 
    subject = models.ForeignKey(Entity) # Entity is unique on a per Entity.name basis 
    object = models.ForeignKey(Entity) # Entity is unique on a per Entity.name basis 

的的ModelForm(PhraseForm)具有字段「主體」是一個CharField。我希望用戶能夠輸入一個字符串。保存模型表單並且字符串與現有實體不匹配時,會創建一個新的實體。

這就是爲什麼我不得不覆蓋模型的「主題」字段,因爲我不能使用模型的自動生成的「主題」字段(我希望我在此明確表達)。

現在,通過模型形式創建新的短語時,所有測試都可以正常運行。但是,修改樂句時:

p = Phrase.objects.latest() 
pf = PhraseForm({'subject': 'anewsubject'}, instance=p). 

pf.is_valid()返回False。我得到的錯誤是「對象」不能爲無。這是有道理的,因爲實際上,對象字段沒有填寫。

什麼是處理的最佳方式?我當然可以檢查是否在PhraseForm的init()函數中提供了一個實例,然後從傳遞的實例中分配缺少的字段值。這並不認爲它是正確的方式,所以,確保實例的數據通過ModelForm傳遞的方法是不是很麻煩?

現在,我打字這一點,我想沒有,因爲底層模型字段被覆蓋,這意味着表單字段值需要再次爲了填補一切工作正常。這讓我重新說明了我的問題:我處理的方式是允許用戶輸入自由文本並將其鏈接到新的或現有的實體,這樣做的正確方法是?

在此先感謝!

回答

1

你爲什麼要使用表單進行修改。

p = Phrase.objects.latest() 
p.subject = Entity.objects.get_or_create(name='anewsubject')[0] 

docs for get_or_create

如果您在實際使用的形式,它應該很好地工作:

def mod_phrase(request, phrase_id=None): 
    phrase = get_object_or_404(Phrase, pk=phrase_id) 

    if request.method == 'POST': 
     form = PhraseForm(request.POST, instance=phrase) 
     if form.is_valid(): 
      form.save() 
      return HttpResponse("Success") 
    else: 
     form = PhraseForm(instance=phrase) 

    context = { 'form': form } 

    return render_to_response('modify-phrase.html', context, 
     context_instance=RequestContext(request)) 

設置爲的ModelForm實例設置初始數據,並且也讓形式知道哪個對象表單正在處理。您嘗試使用表單的方式是,您傳遞的是無效的data字典(缺少object),表單正確地告訴您無效。在上面的示例中將data設置爲request.POST時,request.POST包含允許表單驗證的初始數據。

+0

啊,當。在重讀這篇文章之後,我意識到表單自然期望所有領域的數據。我應該在發佈我的複雜問題之前休息一下......(我使用get_or_create的方式,但在表單中,以便將用戶輸入轉換爲新的或現有的實體)。 – LaundroMat 2011-04-16 14:36:13