如何从 Django ModelChoiceField 查询集中选择值和标签
Posted
技术标签:
【中文标题】如何从 Django ModelChoiceField 查询集中选择值和标签【英文标题】:How to choose the value and label from Django ModelChoiceField queryset 【发布时间】:2013-11-29 12:32:06 【问题描述】:我试图创建一个 django 表单,我的一个字段包含一个 ModelChoiceField
class FooForm(forms.Form):
person = forms.ModelChoiceField(queryset=Person.objects.filter(is_active=True).order_by('id'), required=False)
age = forms.IntegerField(min_value=18, max_value=99, required=False)
当我尝试上面的代码时,它作为 html 输出返回的内容是
<option value="1">Person object</option>
在我的 Person 模型上,我有字段 "id, fname, lname, is_active" 。是否可以指定我的下拉选项将使用“id”作为值并使用“lname”作为标签?预期的 html 应该是
<option value="1">My Last Name</option>
提前致谢!
【问题讨论】:
【参考方案1】:你可以在表单ie的init中添加对label_from_instance的调用
通过添加类似的东西
class TestForm(ModelForm):
def __init__(self, *args, **kwargs):
super(TestForm, self).__init__(*args, **kwargs)
self.fields['field_name'].label_from_instance = self.label_from_instance
@staticmethod
def label_from_instance(obj):
return "My Field name %s" % obj.name
【讨论】:
非常优雅的解决方案。使您能够更改特定表单的模型选择标签。 这是一个很好的解决方案,因为它允许您使用字符串表示之外的其他标签。太好了!!! 太棒了!!这正是所需的,而无需永久更改 str 表示【参考方案2】:来自 Django 文档:
https://docs.djangoproject.com/en/dev/ref/forms/fields/#django.forms.ModelChoiceField
模型的
__unicode__
(Python 3 上的__str__
)方法将是 调用以生成对象的字符串表示形式以用于 领域的选择;提供定制的表示,子类 ModelChoiceField 并覆盖 label_from_instance。这种方法将 接收一个模型对象,并且应该返回一个适合的字符串 代表它。例如:from django.forms import ModelChoiceField class MyModelChoiceField(ModelChoiceField): def label_from_instance(self, obj): return "My Object #%i" % obj.id
因此,您可以这样做,或者在您的模型类上覆盖 __str__
以返回姓氏。
【讨论】:
您好 FogleBird,感谢您的回复。这个解决方案实际上可以为我工作。我只是有一个额外的问题,默认情况下,django ModelChoiceField 是否会在模型中查找某个列以用作选项上的标签? 它首先要查找的是您在模型中定义的 unicode def。正如 FogleBird 所提到的,它在 Python 3 中的 str。 这个答案指向了正确的方向,ModelChoiceField 可以通过提供参数来自定义 你如何实际使用它?我应该把它放在哪里,在模型中还是在表单中?【参考方案3】:在您的 Person 模型中添加:
def __unicode__(self):
return u'0'.format(self.lname)
如果您使用的是 Python 3,则定义 __str__
而不是 __unicode__
。
def __str__(self):
return u'0'.format(self.lname)
【讨论】:
谢谢!为我工作。我只是有一个我已经在上面发布的附加问题,ModelChoiceField 默认情况下会在模型中查找它用作标签的某个列或字段吗? 但这不会将选项值设置为数字,是吗? 但是如果你不想要 unicode 怎么办。你能告诉它用什么吗? @Sloy 它只会以可读的方式改变实例的表示方式。【参考方案4】:您可以将ModelChoiceField
实例的label_from_instance
方法覆盖为您的自定义方法。您可以在表单的__init__
方法内完成
class FooForm(forms.Form):
person = forms.ModelChoiceField(queryset=Person.objects.filter(is_active=True).order_by('id'), required=False)
age = forms.IntegerField(min_value=18, max_value=99, required=False)
def __init__(self, *args, **kwargs):
super(FooForm, self).__init__(*args, **kwargs)
self.fields['person'].label_from_instance = lambda instance: instance.name
【讨论】:
【参考方案5】:要选择/更改可以使用“to_field_name”选项的值, 要更改选项的标签,您可以覆盖 ModelChoiceField 类中的“label_from_instance”函数,
这是一个简单的例子,
forms.py:
from django import forms
from .models import Group
from django.forms import ModelChoiceField
class MyModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return f"My Object obj.group_name"
class MyPureDjangoForm(forms.Form):
group = MyModelChoiceField(queryset=Group.objects.all(),
widget=forms.Select(attrs=
'class': 'form-control'
),
to_field_name='id',
)
欲了解更多信息,请访问以下网址:
https://docs.djangoproject.com/en/3.2/ref/forms/fields/#django.forms.ModelChoiceField
我希望这会有所帮助。
【讨论】:
以上是关于如何从 Django ModelChoiceField 查询集中选择值和标签的主要内容,如果未能解决你的问题,请参考以下文章