我在使用Django时遇到了问题,试图构建一个非常简单(对我来说很丢人......)的事情:我想使用另一个SelectField过滤一个ForeignKey ModelField(例如,使用Ajax:"国家"选择框自动完成"城市"选择框,以便用户可以选择他的城市)。
我的模型看起来像:
class Country(models.Model):
...
class Town(models.Model):
country = models.ForeignKey(Country)
...
class Person(models.Model):
user = models.ForeignKey(User, unique=True)
town = models.ForeignKey(Town, related_name='persons')
...
右。
现在我想要一个表单来创建/更新一个人,允许用户在由另一个选择框(国家/地区)的值过滤的选择框中设置城市。
这是我创建的表格:
class LazyChoiceField(forms.ChoiceField):
def __init__(self, required=True, widget=None, label=None,
initial=None, help_text=None, *args, **kwargs):
super(LazyChoiceField, self).__init__(required=required, widget=widget,
label=label, initial=initial,
help_text=help_text, *args, **kwargs)
def valid_value(self, value):
return True
class PersonForm(ModelForm):
country = ModelChoiceField(queryset=Country.objects.all())
town = LazyChoiceField(choices=[('0', "Chose a country firts!")])
class Meta:
model = Person
exclude = ('user', 'town', )
widgets = {
'country': forms.Select(attrs={'onchange':'get_towns();'}),
}
它可以工作(提供一个 ajax.py 文件,通过 Jquery 脚本通过 Ajax 调用的 get_towns() 函数 + 模板页面上的一些 JS 内容)。但我对这种方式并不满意:排除城镇田地并添加另一个城镇 LazyChoiceField 似乎并不干燥,是吗?
我的问题是:当所选值不在初始查询集中时,是否可以告诉 Django 不要在 ModelField 上生成验证错误(实际上,我无法在表单上渲染数千个城镇!
这个功能(选择国家/城镇)在网络上非常流行,但我没有设法找到一个简单的 Django 片段来做这样的事情。您如何看待我正在尝试开发的解决方案?如何更好地做到这一点并遵循 DRY 原则?
如果我不从模型表单中排除城镇,我的 30000 个城镇选择框会使页面非常慢(并且无法使用)!
提前非常感谢!
很高兴您解决了您的问题。以防万一其他人碰巧,Django 会针对实例化期间传入的choices
构建选择验证。如果你要对选择进行 AJAX 过滤,就 Django 而言,你的choices
必须是每个允许的选择,未过滤。使用javascript在页面呈现后做出任何你喜欢的选择。