Django 国家/城市动态选择:如何在模型字段中允许字段值超出查询集



我在使用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在页面呈现后做出任何你喜欢的选择。

相关内容

最新更新