开发者

Why is self.instance not set in clean function for a bound form?

I have a Django 1.1 model with unique_together on the owner and title where owner is foreign key on a user. This constraint is enforced but only after the clean. According to Django docs, I should be able to access self.instance to see non-form field object properties of a model instance.

However, I get the error

'JournalForm' object has no attribute 'instance'

Why is self.instance not set on this bound form in either the form clean() or the field clean_title() methods?

My model:

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

My form:

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

As requested - the view code:

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_HT开发者_如何转开发ML(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>')


Well there are a couple of issues here.

First is that you're not using a ModelForm. The docs you link to are for those, not for standard forms.

Secondly, in order for the form to have an instance attribute, you need to pass that instance in when you're instantiating the form.

If you do use a ModelForm, you won't need the code that converts the journal fields to the form fields, and vice versa on save - the form does that for you. You'll also be able to remove the clean_title method which checks for uniqueness, because that's already defined by the unique_together constraint on the model, and the ModelForm will enforce that for you.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜