为什么self.instance没有在绑定表单的clean函数中设置?

时间:2010-10-26 16:55:36

标签: django django-forms

我在所有者和标题上有一个带有unique_together的Django 1.1模型,其中所有者是用户的外键。强制执行此约束但仅在清除之后。根据{{​​3}},我应该能够访问self.instance以查看模型实例的非表单字段对象属性。

然而,我收到错误

  

'JournalForm'对象没有属性'instance'

为什么self.instance没有在表单clean()或字段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>')

1 个答案:

答案 0 :(得分:3)

这里有几个问题。

首先,您没有使用ModelForm。您链接的文档适用于那些文档,而不适用于标准表单。

其次,为了使表单具有实例属性,您需要在实例化表单时传递该实例。

如果您确实使用了ModelForm,则不需要将日志字段转换为表单字段的代码,反之亦然 - 保存 - 表单会为您执行此操作。您还可以删除检查唯一性的clean_title方法,因为它已经由模型上的unique_together约束定义,而ModelForm将为您强制执行该操作。