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

时间:2011-05-20 13:32:55

标签: django django-models autocomplete dry

我遇到了Django的问题,尝试构建一个非常简单的(对我来说很遗憾......)的事情:我想使用另一个SelectField(使用Ajax,例如:“Country”选择框)过滤ForeignKey ModelField自动填充“城市”选择框,以便用户可以选择他的城市。

我的模特看起来像:

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文件,提供一个get_towns()函数,通过Jquery脚本通过Ajax调用+模板页面上的一些JS东西)。但我对这种做法并不满意:排除城镇场地并增加另一个城镇LazyChoiceField似乎并不干嘛,是吗?

我的问题是:当选择的值不在初始查询集中时,是否有可能告诉Django不会在ModelField上生成验证错误(实际上,我无法在表单上渲染数千个城镇!)。 / p>

此功能(选择国家/城镇)在网络上非常受欢迎,但我没有设法找到一个简单的Django片段来做这样的事情。您如何看待我正在努力开发的解决方案? 如何更好地遵循DRY原则?

如果我不从ModelForm中排除town,我的30000城镇选择框会使页面变得非常慢(并且无法使用)!

非常感谢你!

1 个答案:

答案 0 :(得分:0)

很高兴你解决了你的问题。为了防止其他任何事情发生,Django针对在实例化期间传入的choices的选择构建验证。如果您要对选择进行AJAX过滤,那么就Django而言,choices必须是每个允许的选择,未经过滤。在呈现页面后,使用javascript进行任何您喜欢的选择。