Django表单:如何动态创建ModelChoiceField标签

Django表单:如何动态创建ModelChoiceField标签,django,django-forms,Django,Django Forms,我想为forms.ModelChoiceField创建动态标签,我想知道如何做到这一点。我有以下表格: class ProfileForm(forms.ModelForm): def __init__(self, data=None, ..., language_code='en', family_name_label='Family name', horoscope_label='Horoscope type', *args, **kwargs): super(Pro

我想为forms.ModelChoiceField创建动态标签,我想知道如何做到这一点。我有以下表格:

class ProfileForm(forms.ModelForm):

    def __init__(self, data=None, ..., language_code='en', family_name_label='Family name', horoscope_label='Horoscope type', *args, **kwargs):
        super(ProfileForm, self).__init__(data, *args, **kwargs)

        self.fields['family_name'].label = family_name_label
        .
        .
        self.fields['horoscope'].label = horoscope_label
        self.fields['horoscope'].queryset = Horoscope.objects.all()

    class Meta:
        model = Profile

    family_name = forms.CharField(widget=forms.TextInput(attrs={'size':'80', 'class': 'contact_form'}))
    .
    .
    horoscope = forms.ModelChoiceField(queryset = Horoscope.objects.none(), widget=forms.RadioSelect(), empty_label=None)
默认标签由配置文件定义中指定的unicode函数定义。但是,需要动态创建ModelChoiceField创建的单选按钮的标签

首先,我认为我可以简单地覆盖Django文档中描述的ModelChoiceField。但这会创建静态标签。它允许您定义任何标签,但一旦做出选择,该选择就固定了

因此,我认为我需要对init添加一些内容,例如:

class ProfileForm(forms.ModelForm):

    def __init__(self, data=None, ..., language_code='en', family_name_label='Family name', horoscope_label='Horoscope type', *args, **kwargs):
        super(ProfileForm, self).__init__(data, *args, **kwargs)

        self.fields['family_name'].label = family_name_label
        .
        .
        self.fields['horoscope'].label = horoscope_label
        self.fields['horoscope'].queryset = Horoscope.objects.all()
        self.fields['horoscope'].<WHAT>??? = ???

您可以使用
modelcooicefield
,然后动态更改
ProfileForm中的选项。\uuu init\uu
,例如(假设它已经是modelcoocefield):


h.name
在本例中将用作选项的标签

您可以创建自己的表单字段类并覆盖生成标签的方法:

class MyChoiceField(ModelChoiceField):
   def label_from_instance(self, obj):
        # return your own label here...
        return smart_unicode(obj)
以与ModelChoiceField相同的形式使用它:

horoscopes = Horoscope.objects.all()
self.fields['horoscope'].choices = [(h.pk, h.name) for h in horoscopes]
horoscope = MyChoiceField(queryset = .....)

实际上,最后一个代码示例包含的错误应该是:

# this function is added
def get_label(obj):
    return '%s: Euro %.2f' % (HoroscopeLanguage.objects.get(horoscope=obj, language__language_code=language_code).horoscope_type_language, obj.price)
.
.
.

self.fields['horoscope'].label_from_instance = get_labels

然后它就起作用了。使用“lambda obj:…”或“def get_label(obj):…”没有区别。

您的意思是“默认标签是在星象定义中指定的
unicode
函数中定义的”?当我尝试您的解决方案时,我得到错误:“选择一个有效的选项。该选项不是可用的选项之一。”恐怕你的解决办法行不通。基本上,模型配置文件定义了一个外键占星术,配置文件实例需要一个模型占星术实例,而不仅仅是一个整数h.pk。是的,我的意思是“默认标签是在占星术定义中指定的unicode函数中定义的”抱歉,我在这里搞错了一些东西,它可能适用于普通的ChoiceField,但是,看看我的另一个解决方案,对ModelChoiceField进行子分类!是的,这也是我在最初的问题中写的。这将创建替代标签,但不创建静态标签。请参阅我的评论:“首先,我认为我可以简单地覆盖Django文档中描述的ModelChoiceField…”
# this function is added
def get_label(obj):
    return '%s: Euro %.2f' % (HoroscopeLanguage.objects.get(horoscope=obj, language__language_code=language_code).horoscope_type_language, obj.price)
.
.
.

self.fields['horoscope'].label_from_instance = get_labels