如何更改表单的小部件是 RadioSelect 的 ForeignKey 字段的默认标签

How to change the default labels of a ForeignKey field whose form's widget is a 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字段的标签是根据Picture模型的__str__()方法生成的。那是因为我的 Profile 模型上的 picture 字段实际上是 Picture 模型的 ForeignKey 字段。

但是,__str__() 方法返回的值在此特定模板中没有多大意义,并且无法更改它,因为它正在其他地方使用。

因此,有没有办法更改 ProfileFormpicture 字段的默认标签?例如,从 __str__() 的默认值 picture.src + ' (' + picture.description + ')' 更改为仅 picture.description 之类的东西?

我已经检查了 what the docs had to say 关于 label_from_instance 的内容,但我不明白如何应用它。事实上,我什至不明白这是否是这个案例的解决方案。

Stack Overflow 上的一些类似问题也提到 link 的文档,但问题的形式与我的略有不同,我最终也没有理解它们。

如果您想使用 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 属性

原来我不需要使用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(),
        }

This section of the docs explains this in greater detail。它实际上描述了如何覆盖 django.forms.Select 选项,但我用 django.forms.RadioSelect 测试了它,它按预期 运行 进行了测试。