2010-10-26 13 views
1

J'ai un modèle Django 1.1 avec unique_together sur le propriétaire et le titre où le propriétaire est une clé étrangère sur un utilisateur. Cette contrainte est imposée mais seulement après le nettoyage. Selon Django docs, je devrais être en mesure d'accéder à self.instance pour voir les propriétés d'objet champ non-formulaire d'une instance de modèle.Pourquoi self.instance n'est-il pas défini comme une fonction propre pour une forme liée?

Cependant, je reçois l'erreur

objet « JournalForm » n'a pas d'attribut « instance »

Pourquoi self.instance pas défini sur cette forme liée soit dans la forme propre() ou le champ clean_title() méthodes?

Mon modèle:

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 

Ma forme:

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 

Comme l'a demandé - le code de la vue:

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

Votre code d'affichage est le bit important ici - pouvez-vous le montrer? –

Répondre

3

Eh bien il y a quelques problèmes ici.

Tout d'abord, vous n'utilisez pas ModelForm. Les documents que vous liez sont pour ceux, pas pour les formulaires standard. Deuxièmement, pour que le formulaire ait un attribut d'instance, vous devez transmettre cette instance lorsque vous instanciez le formulaire. Si vous utilisez un ModelForm, vous n'aurez pas besoin du code qui convertit les champs de journal en champs de formulaire, et vice versa lors de la sauvegarde - le formulaire le fait pour vous. Vous pourrez également supprimer la méthode clean_title qui vérifie l'unicité, car elle est déjà définie par la contrainte unique_together sur le modèle et ModelForm l'appliquera pour vous.

+0

J'ai changé le formulaire en ModelForm, et j'ai essayé de sauvegarder mais j'ai le même problème qu'avant - exception levée: IntegrityError at/labjournal/journal/2 la valeur de la clé en double viole la contrainte unique. Je peux envelopper la sauvegarde dans un bloc try, mais je pensais que ModelForm appliquerait la contrainte unique_together dans le cadre de is_valid(). Est-ce mal? – selfsimilar

+0

Vous ne l'avez pas mentionné auparavant ... Il vaudrait la peine de poster une nouvelle question à ce sujet, avec votre code de vue/formulaire mis à jour. –

+0

Merci, Daniel.Suivez la question ici: http://stackoverflow.com/questions/4034911/why-doesnt-django-enforce-my-unique-together-constraint-as-a-form-validationerro – selfsimilar