2010-10-31 15 views
0

Dans l'admin django, j'ai une ligne dans laquelle je veux que l'utilisateur soit automatiquement renseigné. Au cours de la fonction clean, il remplit le champ created_by avec request.user. Le problème est que puisque le champ created_by est exclu par le formulaire, la valeur qui est insérée dans cleaned_fields est ignorée apparemment. Comment puis-je faire ceci? Je veux que le widget ne soit pas affiché du tout.Exclure un champ de formulaire, mais en le rajoutant avec clean()

class NoteInline(admin.TabularInline): 
    model = Note 
    extra = 1 
    can_delete = False 

    def get_formset(self, request, obj=None, **kwargs): 
     """ 
     Generate a form with the viewing CSA filled in automatically 
     """ 

     class NoteForm(forms.ModelForm): 

      def clean(self): 
       self.cleaned_data['created_by'] = request.user 
       return self.cleaned_data 

      class Meta: 
       exclude = ('created_by',) 
       model = Note 
       widgets = {'note': forms.TextInput(attrs={'style': "width:80%"})} 

     return forms.models.inlineformset_factory(UserProfile, Note, 
                extra=self.extra, 
                form=NoteForm, 
                can_delete=self.can_delete) 

Répondre

2

SUGGESTION ORIGINAL:

Pourquoi ne pas simplement laisser le champ en place, au lieu d'exclure, puis en faire une hiddeninput?

NoteForm classe (forms.ModelForm):

def __init__(*args, **kwargs): 
    super(NoteForm, self).__init__(*args, **kwargs) 

    self.fields['created_by'].widget = forms.widgets.HiddenInput() 


#rest of your form code follows, except you don't exclude 'created_by' any more  

SUGGESTION # 2 (parce que le champ caché apparaît toujours dans l'en-tête de colonne dans la ligne):

Ne pas régler self.cleaned_data [ 'created_by'] dans la méthode clean() du tout. Au lieu de cela, remplacez NoteForm.save() et définissez-le ici.

(soit passer dans la demande d'enregistrement(), si vous le pouvez, ou cache dans init en l'ajoutant à self, ou l'utiliser comme une variable de niveau de classe comme vous semblez le faire déjà.)

+0

qui ne fonctionne pas à cause de cela: http://imgur.com/fbajE.png – priestc

+0

Dans ce cas, il est temps pour un refactoring. Voir l'exemple édité ci-dessus –

0

Ma solution était d'éditer la fonction formfield_for_foreignkey pour le Inline, qui limitait la liste déroulante à l'utilisateur connecté.

class NoteInline(admin.TabularInline): 
    model = Note 
    extra = 1 
    can_delete = False 

    def queryset(self, request): 
     return Note.objects.get_empty_query_set() 

    def formfield_for_foreignkey(self, db_field, request, **kwargs): 
     if db_field.name == 'created_by': 
      # limit the 'created_by' dropdown box to just the CSR user who is 
      # logged in and viewing the page. 
      kwargs['queryset'] = User.objects.filter(pk=request.user.pk) 
     return super(NoteInline, self).formfield_for_foreignkey(db_field, request, **kwargs)