2011-08-28 107 views
3

我有以下的模型类:从表单自定义外键字段保存数据在Django

class ContactPerson(models.Model):    
    name = models.CharField(max_length=30) 

    def __unicode__(self): 
     return self.name 

class Appartment(models.Model): 
    contact_person = models.ForeignKey(ContactPerson) 

问题:在模板文件我想用户填写联系人的姓名,所以我改写contact_person场如下:

class AppartmentSellForm(ModelForm): 
    contact_person = forms.CharField(max_length=30) 

    class Meta: 
     model = Appartment 

在我看来,功能我做了以下数据来自提交表单保存:

def appartment_submit(request): 
    if request.method == "POST": 
     form = AppartmentSellForm(request.POST) 
     if form.is_valid(): 
      appartment = form.save(commit=False) # ERROR HERE 
      cp = models.ContactPerson(name=form.cleaned_data['contact_person']) 
      appartment.contact_person = cp 
      appartment.save() 
      form.save(); 
      return HttpResponseRedirect('/sell/') 
    else: 
     form = AppartmentSellForm() 
    return render_to_response('sell_appartment_form.html', {'form' : form}) 

错误消息

#ValueError at /sell/sell_appartment/appartment_submit/ 

Cannot assign "u'blabla'": "Appartment.contact_person" must be a "ContactPerson" instance.** 

我使用SQLite和Django的版本1.1.1

问题:如何解决这个问题?

+0

这是Django的一个相当旧的版本,是否有你不使用1.3的原因? –

+0

没有特别的理由:) – Asterisk

+0

在解决所有错误和弃用警告后,更新可能会缓解您的进度,这会更好。更多关于主题(带有尘埃的Django技能),如果你打印cp变量,你会得到你所期望的吗? –

回答

1

我认为您放入视图中的代码更适合ModelForm的验证。

覆盖模型表单的clean_contact_person方法并在其中添加代码,以便a)检查名称是否有效,如果是,b)将表单字段的值设置为实际的ContactPerson实例。

喜欢的东西:(把我的头顶部)

class AppartmentSellForm(ModelForm): 
    contact_person = forms.CharField(max_length=30) 

    class Meta: 
     model = Appartment 

    def clean_contact_person(self): 
     name = self.cleaned_data['contact_person'] 
     # check the name if you need to 
     try: 
      # maybe check if it already exists? 
      person = models.ContactPerson.objects.get(name=name) 
     except ContactPerson.DoesNotExist: 
      person = models.ContactPerson(name=name) 
      # you probably only want to save this when the form is saved (in the view) 
     return person 

您的看法仍然可能需要使用commit=False(因为你将需要保存ContactPerson记录)。您可以使用save_m2m方法执行此操作。

关于save_m2m的更多信息the ModelForm documentation以及关于清洁领域的信息the validation documentation

我希望有所帮助,祝你好运!

+0

谢谢...帮助 – Asterisk

0

您可以执行下列操作之一:

  1. 尝试excludecontact_person领域,如提及in point 3 over here
  2. 或在你ModelForm你可以只是没有覆盖领域和Django会呈现为一个ModelChoiceField ,除非你真的希望人们输入一个名字,而不是有一个下拉列表可供选择。
+0

#2不是一个选项,#1如何提供帮助?我不想排除它... – Asterisk

+0

如果你排除它,它可能不会尝试将字符串保存为'ForeignKey'你试过吗? ...或者你可以尝试@adamnfish的建议。 –

相关问题