2010-10-26 50 views
1

我有一個Django 1.1模型,擁有者和標題上的unique_together,所有者是用戶的外鍵。這個約束是強制執行的,但只能在清理完成之後。根據Django docs,我應該可以訪問self.instance來查看模型實例的非表單字段對象屬性。爲什麼self.instance沒有在乾淨的函數中爲綁定表單設置?

但是,我得到的錯誤

「JournalForm」對象有沒有屬性「實例」

爲什麼self.instance不會在任何形式的清潔這種結合形式的設定()或字段clean_title()方法?

我的模型:

class Journal (models.Model): 
    owner = models.ForeignKey(User, null=True, related_name='journals') 
    title = models.CharField(null=False, max_length=256) 
    published = models.BooleanField(default=False) 

    class Meta: 
     unique_together = ("owner", "title") 

    def __unicode__(self): 
     return self.title 

我的形式:

class JournalForm (forms.Form): 
    title = forms.CharField(max_length=256, 
           label=u'Title:') 
    html_input = forms.CharField(widget=TinyMCE(attrs={'cols':'85', 'rows':'40'},), 
          label=u'Journal Content:') 
    published = forms.BooleanField(required=False) 

    def clean(self): 
     super(JournalForm, self).clean() 
     instance = self.instance 
     return self.cleaned_input 

    def clean_title(self): 
     title = self.cleaned_data['title'] 
     if self.is_bound: 
      if models.Journal.objects.filter(owner.id=self.instance.owner.id, title=title).exclude(id=self.instance.id).count() > 0: 
       raise forms.ValidationError(u'You already have a Journal with that title. Please change your title so it is unique.') 
     else: 
      if models.LabJournal.objects.filter(owner.id=self.instance.owner.id, title=title).count() > 0: 
       raise forms.ValidationError(u'You already have a Journal with that title. Please change your title so it is unique.') 
     return title 

按照要求 - 視圖代碼:

def journal (request): 
    try: 
     journal = models.Journal.objects.get(id=id) 
     if request.method == 'GET': 
      if request.user.is_active: 
       if request.user.id == journal.owner.id: 
        data = { 
         'title' : journal.title, 
         'html_input' : _journal_fields_to_HTML(journal.id), 
         'published' : journal.published 
        } 
        form = forms.JournalForm(initial=data) 
        return shortcuts.render_to_response('journal/Journal.html', { 'form':form, }) 
       else: 
        return http.HttpResponseForbidden('<h1>Access denied</h1>') 
      else: 
       return _display_login_form(request) 
     elif request.method == 'POST': 
      if LOGIN_FORM_KEY in request.POST: 
       return _handle_login(request) 
      elif request.user.is_active and request.user.id == journal.owner.id: 
       form = forms.JournalForm(data=request.POST) 
       if form.is_valid(): 
        journal.title = form.cleaned_data['title'] 
        journal.published = form.cleaned_data['title']; 
        journal.save() 
        if _HTML_to_journal_fields(journal, form.cleaned_data['html_input']): 
         html_memo = "Save successful." 
        else: 
         html_memo = "Unable to save Journal." 
        return shortcuts.render_to_response('journal/Journal.html', { 'form':form, 'saved':html_memo}) 
       else: 
        return shortcuts.render_to_response('journal/Journal.html', { 'form':form }) 
     return http.HttpResponseNotAllowed(['GET', 'POST']) 
    except models.Journal.DoesNotExist: 
     return http.HttpResponseNotFound('<h1>Requested journal not found</h1>') 
+0

您的視圖代碼在這裏很重要 - 您可以展示它嗎? – 2010-10-26 17:02:33

回答

3

那麼有幾個問題在這裏。

首先是你沒有使用ModelForm。您鏈接的文檔適用於那些文檔,而不適用於標準表單。

其次,爲了使表單具有實例屬性,您需要在實例化表單時傳遞該實例。

如果您確實使用了ModelForm,則不需要將日記字段轉換爲表單字段的代碼,反之亦然 - 表單可以幫助您。您還可以刪除檢查唯一性的方法clean_title,因爲這已由模型上的unique_together約束定義,並且ModelForm將爲您執行該方法。

+0

我將表單更改爲ModelForm,並嘗試保存,但遇到與以前相同的問題 - 拋出異常:重複鍵值違反了唯一約束。我可以將保存包裝在try塊中,但我認爲ModelForm會強制unique_together約束作爲is_valid()的一部分。這是錯的嗎? – selfsimilar 2010-10-26 21:56:25

+0

你以前沒有提過......用你最新的視圖/表單代碼來發佈一個新的問題值得。 – 2010-10-27 08:13:17

+0

謝謝,Daniel.Follow問題在這裏:http://stackoverflow.com/questions/4034911/why-doesnt-django-enforce-my-unique-together-constraint-as-a-form-validationerro – selfsimilar 2010-10-27 15:29:22

相關問題