Как изменить метки по умолчанию для поля ForeignKey, виджет формы которого представляет собой RadioSelect
В моем приложении Django у меня есть такая форма:
from django import forms
from main.models import Profile
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['picture']
widgets = {
'picture': forms.RadioSelect(),
}
По умолчанию метки поля picture
в шаблоне генерируются в соответствии с методом __str__()
модели Picture
. Это происходит потому, что поле picture
в моей модели Profile
фактически является полем ForeignKey для модели Picture
.
Однако значение, возвращаемое этим методом __str__()
, не имеет особого смысла в данном конкретном шаблоне, и изменить его невозможно, поскольку оно используется в другом месте.
Поэтому, есть ли способ изменить метки по умолчанию для поля picture
в моем ProfileForm
? Например, изменить стандартные __str__()
по умолчанию picture.src + ' (' + picture.description + ')'
на что-то вроде picture.description
только
Я проверил что сказано в документации относительно label_from_instance
, но я не понял, как это применить. На самом деле, я даже не мог понять, будет ли это решением для данного случая.
В некоторых похожих вопросах здесь, на Stack Overflow, также упоминалась эта ссылка из документации, но формы вопросов немного отличались от моих, и в итоге я их тоже не понял.
Если вы хотите использовать label_from_instance
, вы должны сделать специальный виджет с:
class PictureField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.description
class ProfileForm(forms.ModelForm):
picture = PictureField(Picture.objects)
class Meta:
model = Profile
С другой стороны, вы можете использовать ваш код и в функции init вашей формы, чтобы изменить choices
атрибут поля picture
Оказалось, что мне не нужно было использовать label_from_instance
. Мне просто нужно было создать подкласс django.forms.RadioSelect и переопределить его метод create_option()
, установив метку, задав option['label']
нужное мне значение, вот так:
from django import forms
from main.models import Profile
class PictureRadioSelect(forms.RadioSelect):
def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
option = super().create_option(name, value, label, selected, index, subindex, attrs)
option['label'] = value.instance.description
return option
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['picture']
widgets = {
'picture': PictureRadioSelect(),
}
В этом разделе документации это объясняется более подробно. На самом деле там описывается, как переопределить опции django.forms.Select, но я протестировал это с django.forms.RadioSelect и все прошло как ожидалось.