2010-10-19 3 views
13

У меня есть модель, которая ссылается на поле ForeignKey(User).Django show get_full_name() вместо или имя пользователя в форме модели

Когда пользователь выбирает элемент в своей форме, я хотел бы, чтобы они могли видеть get_full_name(), а не только username.

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

Всегда указывайте свой класс модели в единственном числе, напишите 'Book' вместо' Books'. –

+0

Возможный дубликат [Django forms: как динамически создавать метки ModelChoiceField] (http://stackoverflow.com/questions/2958792/django-forms-how-to-dynamically-create-modelchoicefield-labels) –

ответ

32

Это можно сделать несколькими способами.

Создайте прокси-подкласс User и переопределите его метод __unicode__(), чтобы вернуть полное имя пользователя.

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

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

Теперь в вашей модели формы, используйте UserFullName для извлечения пользователей.

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

Другой способ динамического заполнения выбор в конструкторе формы.

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 

Пожалуй, самый "djangonic" способ демонстрируется lazerscience как ответ на аналогичный вопрос Django forms: how to dynamically create ModelChoiceField labels. Он подклассы ModelChoiceField и переопределяет его метод label_from_instance(), который предназначен для предоставления меток выбора.

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

Спасибо, последний вариант (самый «джангоничный» способ) кажется самым чистым и отлично работает. Не забывайте «из django.utils.encoding import smart_unicode». – SaeX

+0

Спасибо за этот ответ, вы поможете мне решить проблему –

0

В дополнение к ответу Török Габора, следующее может быть использовано для ModelMultipleChoiceField с:

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) 

Обратите внимание, что у меня есть копия help_text так справки по умолчанию текст, который ("Использовать контроль или команду, чтобы выбрать несколько ... ').

Смежные вопросы