2011-04-15 83 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