开发者

How to display a user's get_full_name() instead of the username in a Django model form?

开发者 https://www.devze.com 2023-01-20 08:09 出处:网络
I have a model that references a ForeignKey(User) field. When a user selects an item on his form I would like them to be able to see the开发者_如何学Go get_full_name() instead of just the username.

I have a model that references a ForeignKey(User) field.

When a user selects an item on his form I would like them to be able to see the开发者_如何学Go get_full_name() instead of just the username.

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


This can be done several ways.

Create a proxy subclass of User and override its __unicode__() method to return user's full name.

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

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

Now in your model form, use UserFullName to retrieve users.

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

Another way is to dynamically populate choices in form's constructor.

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

Perhaps, the most "djangonic" way is demonstrated by lazerscience as an answer to the similar question Django forms: how to dynamically create ModelChoiceField labels. It subclasses ModelChoiceField and overrides its label_from_instance() method that is intended to provide choice labels.

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


In addition to Török Gábor's answer, the following can be used for ModelMultipleChoiceFields:

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)

Note that I have copy help_text so the default help text ('Use control or command to select multiple...').

0

精彩评论

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