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

Вернуться на верх