我目前正在使用wtf处理地址表格,其中包含国家/地区,州/省,城市等。数据库全部用FK设置。
class Country(db.Model): __tablename__ = 'countries' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) users = db.relationship('User', backref='countries', lazy='dynamic') class City(db.Model): __tablename__ = 'cities' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) countries_id = db.Column(db.Integer, db.ForeignKey('countries.id'))
现在,我正在尝试实现链式选择字段排序效果,以优化用户体验。所需的效果是无需离开或刷新页面即可使selectfield提取数据取决于先前的selectfield。
例如,用户在“国家”中选择“澳大利亚”,那么“州”的第二个选择字段应仅包含“澳大利亚”中的州。
我已经对该主题进行了一些研究,但无法提出令人满意的解决方案。这是我发现的两个可能但又不容忽视的解决方案。
1.使用jQuery插件,例如链式。但是,此插件需要逐行编码。如果我采用这种解决方案,那么至少还会有400多行代码,而这并不是很pythonic。例如:
<select id="series" name="series"> <option value="">--</option> <option value="series-3" class="bmw">3 series</option> <option value="series-5" class="bmw">5 series</option> <option value="series-6" class="bmw">6 series</option> <option value="a3" class="audi">A3</option> <option value="a4" class="audi">A4</option> <option value="a5" class="audi">A5</option> </select>
2.使用Wtf的“具有动态选择值的选择字段”,这也是不希望的,因为它仅根据以前选择字段的默认值提取一次数据。例如:如果国家/地区的默认选择字段是澳大利亚,则州选择字段将仅包含澳大利亚内的州。当您将国家/地区选择字段更改为“美国”时,州/地区选择字段仍将仅包含澳大利亚内的州。以下是wtf文档中列出的有关此方法的教程:
class UserDetails(Form): group_id = SelectField(u'Group', coerce=int) def edit_user(request, id): user = User.query.get(id) form = UserDetails(request.POST, obj=user) form.group_id.choices = [(g.id, g.name) for g in Group.query.order_by('name')]
根据以上研究,我认为令人满意的解决方案应该介于两者之间,并且肯定应该包含一些Java脚本来监视客户端活动,而不向服务器发送请求。有人对Flask框架有令人满意的解决方案吗?
如果您希望客户端动态处理某些内容,则无法编写一些JavaScript。幸运的是,这不是您估计的400多条线。此示例未使用WTForms,但这并不是很重要。关键部分是将可用选项作为JSON发送,并动态更改可用选项。这是一个可运行的单文件Flask应用程序,演示了基本思想。
from flask import Flask, render_template_string app = Flask(__name__) @app.route('/') def index(): systems = { 'PlayStation': ['Spyro', 'Crash', 'Ico'], 'N64': ['Mario', 'Superman'] } return render_template_string(template, systems=systems) template = """ <!doctype html> <form> <select id="system"> <option></option> </select> <select id="game"></select> <button type="submit">Play</button> </form> <script src="//code.jquery.com/jquery-2.1.1.min.js"></script> <script> "use strict"; var systems = {{ systems|tojson }}; var form = $('form'); var system = $('select#system'); var game = $('select#game'); for (var key in systems) { system.append($('<option/>', {'value': key, 'text': key})); } system.change(function(ev) { game.empty(); game.append($('<option/>')); var games = systems[system.val()]; for (var i in games) { game.append($('<option/>', {'value': games[i], 'text': games[i]})); } }); form.submit(function(ev) { ev.preventDefault(); alert("playing " + game.val() + " on " + system.val()); }); </script> """ app.run()