Python DJANGO:ModelChoiceField optgroup标记
如何在ModelChoiceField optgroup标记中设置 例如: models.py forms.py 我希望将我的选择字段呈现如下: example.html **更新** 我这样解决了我的问题: 这里有一个很好的片段: 选择字段和带有可选optgroup的选择小部件:Python DJANGO:ModelChoiceField optgroup标记,python,django,django-templates,django-forms,Python,Django,Django Templates,Django Forms,如何在ModelChoiceField optgroup标记中设置 例如: models.py forms.py 我希望将我的选择字段呈现如下: example.html **更新** 我这样解决了我的问题: 这里有一个很好的片段: 选择字段和带有可选optgroup的选择小部件: 您不需要创建任何自定义字段,Django已经完成了这项工作,只需将选项以良好格式传递: MEDIA_CHOICES = ( ('Audio', ( ('vinyl', 'Vinyl'), ('cd',
您不需要创建任何自定义字段,Django已经完成了这项工作,只需将选项以良好格式传递:
MEDIA_CHOICES = (
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
)
要与一起使用的@Stefan Manastirliu answer的扩展。缺点是下面的get_tree_data函数只允许一个级别。与javascript插件(如)结合使用,您可以获得多选功能 Models.py forms.py ModelChoiceField使用ModelChoiceIterator将查询集转换为选项列表。 您可以轻松重写此类以引入组。 以下是按国家对城市进行分组的示例: 从itertools导入groupby 从django.forms.models导入ModelChoiceField、ModelChoiceInterator 来自。模型导入城市 类别CityChoiceInteratorModelChoiceInterator: 定义自身: queryset=self.queryset.选择与“国家”相关的名称。按“国家名称”、“名称”排序 groups=groupbyqueryset,key=lambda x:x.country 对于国家、城市分组: 屈服[ country.name, [ city.id,city.name 城市中的城市 ] ] 类别城市选择场模式选择场: 迭代器=城市选择迭代器 定义初始自我,*args,**kwargs: super.\uuuu init\uuuu City.objects.all,*args,**kwargs
注意:我没有时间检查此技术是否与Django3.1中引入的新技术兼容。Yap,这是一个非常好的代码片段。我遵循这些指示。。。TNXXI如果有人想用ChoiceField进行多层次的嵌套,我在我的博客上写了一个方法:但这对ChoiceField有效,而不是ModelChoiceField,对吗?他要求使用ModelChoiceField,但这并不能解决问题。回答错误。这回答了你的问题吗?
class LinkForm(ModelForm):
config = ModelChoiceField(queryset=Config.objects.all(), empty_label="Choose a link",widget=GroupedSelect())
class Meta:
model = Link
<select id="id_config" name="config">
<option selected="selected" value="">Choose a link</option>
<optgroup label="Configuration" >
<option value="8">Address: 192.168.1.202/255.255.255.0 </option>
<option value="9">Address: 192.168.1.240/255.255.255.0 </option>
<option value="10">Address: 192.168.3.1/255.255.255.0 </option>
</optgroup>
</select>
class GroupedSelect(Select):
def render(self, name, value, attrs=None, choices=()):
if value is None: value = ''
final_attrs = self.build_attrs(attrs, name=name)
output = [format_html('<select{0}>', flatatt(final_attrs))]
for index, option_gp in enumerate(self.choices):
if index == 0:
option_value = smart_unicode(option_gp[0])
option_label = smart_unicode(option_gp[1])
output.append(u'<option value="%s">%s</option>' % (escape(option_value), escape(option_label)))
output.append('<optgroup label = "Configuration">')
elif index!=0 and index <= len(self.choices):
option_value = smart_unicode(option_gp[0])
option_label = smart_unicode(option_gp[1])
output.append(u'<option value="%s">%s</option>' % (escape(option_value), escape(option_label)))
output.append(u'</optgroup>')
output.append(u'</select>')
return mark_safe('\n'.join(output))
MEDIA_CHOICES = (
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
)
from categories.models import CategoryBase
class SampleCategory(CategoryBase):
class Meta:
verbose_name_plural = 'sample categories'
class SampleProfile(models.Model):
categories = models.ManyToManyField('myapp.SampleCategory')
from myapp.models import SampleCategory
def get_tree_data():
def rectree(toplevel):
children_list_of_tuples = list()
if toplevel.children.active():
for child in toplevel.children.active():
children_list_of_tuples.append(tuple((child.id,child.name)))
return children_list_of_tuples
data = list()
t = SampleCategory.objects.filter(active=True).filter(level=0)
for toplevel in t:
childrens = rectree(toplevel)
data.append(
tuple(
(
toplevel.name,
tuple(
childrens
)
)
)
)
return tuple(data)
class SampleProfileForm(forms.ModelForm):
categories = forms.MultipleChoiceField(choices=get_tree_data())
class Meta:
model = SampleProfile