如何更改表单的小部件是 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__()
方法返回的值在此特定模板中没有多大意义,并且无法更改它,因为它正在其他地方使用。
因此,有没有办法更改 ProfileForm
的 picture
字段的默认标签?例如,从 __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 测试了它,它按预期 运行 进行了测试。
在我的 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__()
方法返回的值在此特定模板中没有多大意义,并且无法更改它,因为它正在其他地方使用。
因此,有没有办法更改 ProfileForm
的 picture
字段的默认标签?例如,从 __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 测试了它,它按预期 运行 进行了测试。