2010-10-19 18 views
13

J'ai un modèle qui fait référence à un champ ForeignKey(User).Django show get_full_name() à la place ou nom d'utilisateur sous forme de modèle

Lorsqu'un utilisateur sélectionne un élément sur son formulaire, je voudrais qu'il puisse voir le get_full_name() au lieu de seulement le username.

class Books(models.Model): 
    author = models.ForeignKey(User) 
+3

Toujours nommer votre classe de modèle au singulier, écrivez 'Book' au lieu de' Books'. –

+0

duplication possible de [formulaires Django: comment créer dynamiquement des étiquettes ModelChoiceField] (http://stackoverflow.com/questions/2958792/django-forms-how-to-dynamically-create-modelchoicefield-labels) –

Répondre

32

Cela peut être fait de plusieurs façons.

Créer une sous-classe proxy de User et remplacer sa méthode __unicode__() pour renvoyer le nom complet de l'utilisateur.

class UserFullName(User): 
    class Meta: 
     proxy = True 

    def __unicode__(self): 
     return self.get_full_name() 

Maintenant, dans votre modèle de formulaire, utilisez UserFullName pour récupérer les utilisateurs.

class BookForm(forms.ModelForm): 
    author = forms.ModelChoiceField(queryset=UserFullName.objects.all()) 
    class Meta: 
     model = Book 

Une autre façon est de remplir dynamiquement des choix dans le constructeur de forme.

class BookForm(forms.ModelForm): 

    def __init__(self, *args, **kwargs): 
     super(BookForm, self).__init__(*args, **kwargs) 
     users = User.objects.all() 
     self.fields['author'].choices = [(user.pk, user.get_full_name()) for user in users] 

    class Meta: 
     model = Book 

Peut-être, la façon la plus "djangonic" est démontrée par lazerscience comme une réponse à la question similaire Django forms: how to dynamically create ModelChoiceField labels. Il sous-classe ModelChoiceField et remplace sa méthode label_from_instance() qui est destinée à fournir des étiquettes de choix.

class UserFullnameChoiceField(forms.ModelChoiceField): 
    def label_from_instance(self, obj): 
     return smart_unicode(obj.get_full_name()) 

class BookForm(forms.ModelForm): 
    author = UserFullnameChoiceField(queryset=User.objects.all()) 

    class Meta: 
     model = Book 
+0

Merci, la dernière option (la manière la plus "djangonique") semble la plus propre et a bien fonctionné. Ne pas oublier un 'from django.utils.encoding import smart_unicode'. – SaeX

+0

Merci pour cette réponse tu m'aidies à résoudre le problème –

0

En plus de la réponse de Török Gábor, les éléments suivants peuvent être utilisés pour ModelMultipleChoiceField s:

class UserFullnameMultipleChoiceField(ModelMultipleChoiceField): 
    def label_from_instance(self, obj): 
     return smart_unicode(obj.get_full_name()) 

class BookForm(forms.ModelForm): 
    authors = UserFullnameMultipleChoiceField(queryset=User.objects.all(), 
               help_text=Book.authors.field.help_text) 

Notez que j'ai copie help_text de sorte que le texte d'aide par défaut («Utiliser le contrôle ou la commande pour sélectionner plusieurs ... ').