Как изменить метки по умолчанию для поля 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 и все прошло как ожидалось.