Django/jQuery 级联选择框? [英] Django/jQuery Cascading Select Boxes?

查看:28
本文介绍了Django/jQuery 级联选择框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想构建一个国家/州选择器.首先选择一个国家,该国家的州显示在第二个选择框中.在 PHP 和 jQuery 中这样做相当容易,但我发现 Django 表单在这个意义上有点限制.

I want to build a Country/State selector. First you choose a country, and the States for that country are displayed in the 2nd select box. Doing that in PHP and jQuery is fairly easy, but I find Django forms to be a bit restrictive in that sense.

我可以在页面加载时将 State 字段设置为空,然后用一些 jQuery 填充它,但是如果出现表单错误,它将无法记住"您选择的 State.我也很确定它会引发验证错误,因为您的选择不是 Python 方面的表单中列出的选项之一.

I could set the State field to be empty on page load, and then populate it with some jQuery, but then if there are form errors it won't be able to "remember" what State you had selected. I'm also pretty sure that it will throw a validation error because your choice wasn't one of the ones listed in the form on the Python side of things.

那么我该如何解决这些问题?

So how do I get around these problems?

推荐答案

你可以设置一个隐藏字段来拥有真正的状态"值,然后使用jQuery创建 元素中选择正确的项目.

You could set a hidden field to have the real "state" value, then use jQuery to create the <select> list and, on .select(), copy its value to the hidden field. Then, on page load, your jQuery code can fetch the hidden field's value and use it to select the right item in the <select> element after it's populated.

这里的关键概念是 State 弹出菜单是一个完全用 jQuery 创建的虚构作品,而不是 Django 表单的一部分.这让您可以完全控制它,同时让所有其他字段正常工作.

The key concept here is that the State popup menu is a fiction created entirely in jQuery and not part of the Django form. This gives you full control over it, while letting all the other fields work normally.

还有另一种方法,但它不使用 Django 的表单类.

There's another way to do it, but it doesn't use Django's form classes.

在视图中:

context = {'state': None, 'countries': Country.objects.all().order_by('name')}
if 'country' in request.POST:
    context['country'] = request.POST['country']
    context['states'] = State.objects.filter(
        country=context['country']).order_by('name')
    if 'state' in request.POST:
        context['state'] = request.POST['state']
else:
    context['states'] = []
    context['country'] = None
# ...Set the rest of the Context here...
return render_to_response("addressform.html", context)

然后在模板中:

<select name="country" id="select_country">
    {% for c in countries %}
    <option value="{{ c.val }}"{% ifequal c.val country %} selected="selected"{% endifequal %}>{{ c.name }}</option>
    {% endfor %}
</select>

<select name="state" id="select_state">
    {% for s in states %}
    <option value="{{ s.val }}"{% ifequal s.val state %} selected="selected"{% endifequal %}>{{ s.name }}</option>
    {% endfor %}
</select>

您还需要常用的 JavaScript 来在国家/地区更改时重新加载州选择器.

You'll also need the usual JavaScript for reloading the states selector when the country is changed.

我还没有测试过这个,所以它可能有几个漏洞,但它应该能理解.

I haven't tested this, so there are probably a couple holes in it, but it should get the idea across.

所以你的选择是:

  • 在 Django 表单中使用隐藏字段作为实际值,并通过 AJAX 在客户端创建选择菜单,或
  • 抛弃 Django 的表单内容并自己初始化菜单.
  • 创建一个自定义 Django 表单小部件,我没有t 完成,因此不会发表评论.我不知道这是否可行,但看起来您需要在 MultiWidget 中添加几个 Select ,后者在常规文档中没有记录,所以您必须阅读源代码.
  • Use a hidden field in the Django form for the real value and have the select menus created client-side via AJAX, or
  • Ditch Django's Form stuff and initialize the menus yourself.
  • Create a custom Django form widget, which I haven't done and thus will not comment on. I have no idea if this is doable, but it looks like you'll need a couple Selects in a MultiWidget, the latter being undocumented in the regular docs, so you'll have to read the source.

这篇关于Django/jQuery 级联选择框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆