在ModelChoiceField-Django中添加多个标签
我有这样的模型:在ModelChoiceField-Django中添加多个标签,django,django-forms,Django,Django Forms,我有这样的模型: class Cities(models.Model): country = models.CharField(max_length=45, blank=True, null=True) city = models.CharField(max_length=45, blank=True, null=True) def get_city_name(self): if self.sub_species: return
class Cities(models.Model):
country = models.CharField(max_length=45, blank=True, null=True)
city = models.CharField(max_length=45, blank=True, null=True)
def get_city_name(self):
if self.sub_species:
return str(self.country) + " " + str(self.city)
使用我的模型中的示例数据:
France Paris
France Lyon
France Marseille
Germany Berlin
Germany Bonn
views.py
forms.py
在“我的模板”“我的选择”字段中,呈现前面列出的城市列表
但我想要这样的选择:
France
France Paris
France Lyon
France Marseille
Germany
Germany Berlin
Germany Bonn
用户也可以选择一个国家(在我可以选择城市之后)您可以对
modelcoocefield.iterator
进行一些神奇的更改,但是此属性没有文档记录,使用风险自负
否则,我认为您需要编写一个自定义的ChoiceField
class ModelChoiceIterator(forms.models.ModelChoiceIterator):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.seen = set()
def __iter__(self):
for id, label in super().__iter__():
country = label.split(' ')[0]
if country not in self.seen:
yield (id, country)
self.seen.add(country)
yield (id, label)
class CityNameChoiceField(forms.ModelChoiceField):
iterator = ModelChoiceIterator
def label_from_instance(self, obj):
return obj.get_city_name()
有一种更简单的方法可以实现你想要的东西,只需按照以下步骤组织选择。祝你好运:)
添加您的模板代码。我非常惊讶。这是我想做的。完美答案!如果没有重写
类modelcooceiterator
,我认为不需要编写新的选择字段。
France
France Paris
France Lyon
France Marseille
Germany
Germany Berlin
Germany Bonn
class ModelChoiceIterator(forms.models.ModelChoiceIterator):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.seen = set()
def __iter__(self):
for id, label in super().__iter__():
country = label.split(' ')[0]
if country not in self.seen:
yield (id, country)
self.seen.add(country)
yield (id, label)
class CityNameChoiceField(forms.ModelChoiceField):
iterator = ModelChoiceIterator
def label_from_instance(self, obj):
return obj.get_city_name()
def cities_as_choices():
choices = []
for country in models.Cities.objects.values('country').distinct():
new_country = []
cities = []
new_country.append(country.get('country'))
for city in models.Cities.objects.filter(country=country.get('country')):
cities.append([city.pk, city.city])
new_country.append(cities)
choices.append(new_country)
return choices
class CityNameForm(forms.Form):
"""
CityNameForm Class
"""
def __init__(self, *args, **kwargs):
super(CityNameForm, self).__init__(*args, **kwargs)
self.fields['cityName'].choices = cities_as_choices()
cityName = forms.ChoiceField(
choices=cities_as_choices(),
help_text="",
required=False,
label='Cities',
)