Вопрос:
У меня есть модель, которая ссылается на поле ForeignKey(User).
Когда пользователь выбирает элемент в своей форме, я бы хотел, чтобы они могли видеть get_full_name(), а не только username.
class Books(models.Model): author = models.ForeignKey(User) Лучший ответ:
Это можно сделать несколькими способами.
Создайте прокси-подкласс 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
Возможно, самый “джангонический” способ демонстрируется лазерой как ответ на аналогичный вопрос формы Django: как динамически создавать метки ModelChoiceField. Он подклассы 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 Ответ №1
В дополнение к ответу Török Gábor для 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)
Обратите внимание, что у меня есть копия help_text, поэтому текст справки по умолчанию ( “Использовать элемент управления или команду для выбора нескольких…” ).