2011-08-28 146 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的建議。 –

相關問題