wtforms SelectField 怎么动态添加option项

wtforms SelectField 怎么动态添加option项,第1张

jquery写法

1

2

3

4

5

<select name="myselect" id="myselect">

<option value="opt1">选项1</option>

<option value="opt2">选项2</option>

<option value="opt3">选项3</option>

</select>

1

2

3

4

$("#myselect").change(function(){

var opt=$("#myselect").val()

...

})

1. 编辑: 如果你想始终呈现字段禁用某些选项,你必须创建自己的自定义窗口小部件,并现场提供的渲染器。 当前渲染器只需要三个选项在它的元组的选择:(value, name, selected)。 你会需要修改,接受第四个可选的禁用。 基于在wtforms.widget选择类:class SelectWithDisable(object):

"""

Renders a select field.

If `multiple` is True, then the `size` property should be specified on

rendering to make the field useful.

The field must provide an `iter_choices()` method which the widget will

call on renderingthis method must yield tuples of

`(value, label, selected, disabled)`.

"""

def __init__(self, multiple=False):

self.multiple = multiple

def __call__(self, field, **kwargs):

kwargs.setdefault('id', field.id)

if self.multiple:

kwargs['multiple'] = 'multiple'

html = [u'<select %s>' % html_params(name=field.name, **kwargs)]

for val, label, selected, disabled in field.iter_choices():

html.append(self.render_option(val, label, selected, disabled))

html.append(u'</select>')

return HTMLString(u''.join(html))

@classmethod

def render_option(cls, value, label, selected, disabled):

options = {'value': value}

if selected:

options['selected'] = u'selected'

if disabled:

options['disabled'] = u'disabled'

return HTMLString(u'<option %s>%s</option>' % (html_params(**options), escape(unicode(label))))

然后根据在wtforms.fields代码,子类已经存在的SelectFieldclass SelectFieldWithDisable(SelectFiel):

widget = widgets.SelectWithDisable()

def iter_choices(self):

for value, label, selected, disabled in self.choices:

yield (value, label, selected, disabled, self.coerce(value) == self.data)

注意:这不是测试或甚至可以运行Python代码,而是一个非常快速破解给出的问题,并从WTFORMS底层代码。但它应该给你足够的头部与答案完全控制现场开始沿。 使用CSS和JavaScript来控制呈现在页面上。 无论在什么模板渲染系统(I'瓶中 CodeGo.net,神社和wtforms)您呈现您提供一个id或class属性,当你渲染。 (我只是打印form.select_field_variable_name) 然后生成一个CSS文件来控制你的建模JavaScript来控制某些等定制禁用 编辑: 如果你有:<select id=selector>

<option id=value1 value=1>Bananas</option>

<option id=value2 value=2>Corn</option>

<option id=value3 value=3>Lolcats</option>

</select>

您可以将背景色:<style>

#selector {background-color: #beef99}

</style>

并启用/禁用与:<script>

option = document.getElementById('value3')

option.disabled = true

</script>

没看form有关的源码,但是应该是这样的∶

首先,你得理解像flask这种MVC(或者说MTC)的基本运行机制。

- 对于flask的view,你得知道wsgi协议(如果不清楚,请自行Google之)。

更底层(逻辑上的底层)的HTTP utils(flask用的是werkzeug)将client端的HTTP requests等进行parse,并且将其构建为wsgi的environment(包含了request及其他信息)。

wsgi

server在process请求的过程是:根据wsgi协议构建environ,将其传入flask app

instance(这个即为flask框架实现的wsgi app),flask app

instance用这个environ和自己的``start_response``

method(这个也是uwsgi协议规约)完成请求处理并response。

flask有一个线程级(或greenlet)的request对象。在真正process response之前,将environ丢到这个request对象里,之后这个request跟着你的那个线程就成为了默契的炮友~~直至response完成或线程完蛋。

views里面的那一坨坨的route的作用是啥捏?这个就是url routing了,就是我在你的站点上点了一个特定的url,flask要如何满足你。你得说出你想要的东西吧。

那么views是什么时候用到呢?废话,当然还是在接收并理解请求之后到响应之前。

了,flask app instance在处理你的需求的时候从request对象里拿到了你请求的url,这个就相当于一把key,然后app

instance根据这个key去views里找到了对应的锁(你想要的处理逻辑,就是views里的route下面的function),这个锁啊,她

一旦被打开了,满足你需求的时刻也就快了 ~ ~

P.S. 至于如何匹配到这个锁的呢,这个就是url mapping了,就是一堆正则匹配(别小看这个,如果你用过flask的blueprint,你会明白写这么个mapping也是件爽hi了的事情咯)

- model &controller呢?

你的需求其实就是要flask给你response,response其实呢就是数据(不管是RESTFUL API还是template形式,都是你撸出的data)。

数据这坨翔实怎么来的呢?就是你从数据库(广义,包括sql &nosql db,内存级缓存,磁盘文件等等等等)拿到的,至于data的来源嘛,可能是你自己插的,或者是从别的地方哭着要来的。

model

就是干这活的,只不过它比较抽象,将数据库 *** 作转成了对Python对象的 *** 作(这个就是大名鼎鼎的ORM,其实并没有什么卵用,ORM写多了你连查询优

化都忘了,如果你有比较高的performance需求也有很多时间,就自己撸高效检索方案吧,我没少被这玩意儿坑%>_<%)。

controller这玩意儿你其实可以不要,不过为了做逻辑分离,让你撸业务撸的漂亮点儿还是用它吧。

OK,说了这么多,不知道有没有人能看懂,如果没看懂,让我思考会儿吧 ~ ~

========================================================================

简而言之呢,你用flask作application的时候,MVC各司其职堆好你产生data的逻辑即可,其它你一概不用管。

靠,终于可以回到你的问题上了:

先看下Form这玩意儿:

from flask.ext.wtf import Form

from wtforms import StringField, SubmitField

from wtforms.validators import Required

class NameForm(Form):

name = StringField('What is your name?', validators=[Required()])

submit = SubmitField('Submit')

这就是一个类而已,和model里面的那些玩意儿没本质区别,也都是一个映射关系。model是将数据库啥的和Python对象映射;Form是将HTML表单(form)和这个从flask.ext.wtf.Form及其子类映射。

再来看看这玩意儿:

1 @app.route('/', methods=['GET', 'POST'])

2 def index():

3 name = None

4 form = NameForm()

5 if form.validate_on_submit():

6 name = form.name.data

7 form.name.data = ''

8 return render_template('index.html', form=form, name=name)

首先来分析一下执行过程:

哎呀,这个只是个route嘛,它哪有执行过程。

执行是由app instance做的嘛,好吧,其实它是被app instance做的。

展开之前看一下route后面那个 methods=['GET',

'POST']。这玩意的意思是说,当我遇到有与``index``(即上面route下面的那个index)匹配的的请求时,我可以用GET或者

POST方法,其他的像PUT、DELETE等HTTP verb我不让你丫玩儿。

当你把你的这个flask应用deploy到web server或者在本地run test server的时候,你在浏览器里输入 http://xxxxxx.ooooo.xxoo/index 的时候,你向server发射的是``GET``炮d,flask instance接受了你的d,然后route到了index这个函数,好吧,激动人心的时刻到了:

#3. name = None 这个就是个赋值

#4. form = NameForm() 好吧,这个就是NameForm类的实例化,拿到一个form object。

#5.

if form.validate_on_submit():呵呵,这个嘛,意思是问一下#2中实例化的form

object,SB,你是在被人(1)submit(提交)并且(2)提交满足我的要求么?

好吧,前面说过了,我是在GET,而没有在submit(submit在HTML中为POST),好吧,我连(1)都不满足,所以也就没有#6、#7什么

事儿了。

#8 好的,app instance终于快要向你回馈了。给我把前面的from object和name变量一起带到index.html这个文件里吧。

哈哈,终于有jinja2的活儿了,@题主, 你丫也把index.html发上来呀 = =

index.html

里你写了个表单,里面有个叫做``name``的field和一个``submit``按钮,这些field和你的``NameForm``对应,好了,

对应填充的活儿和就交给jinja2吧,它会给你一个最终将在用户浏览器显示的index.html。

view的使命完成了,它成功的生成了数据。

app instance 拿到了view的数据,也该向client端发最终响应了。OK,server完成了这次request的response,用户拿到最终想要的东西了。

浏览器或者UA干的活儿我就不展开了,我的手已经抽筋了,

现在在用户的浏览器上,看到了index.html,上面有一个表单,那个表单上面有个文本框(有``What is your name?``的placeholder)和一个Submit提交按钮。

了,用户在那个文本框中写了一个名字,比如``John``,然后按了那个``Submit``按钮,这次提交回向server发射一个``POST``

请求,这个请求里面会带上文本框的名字(哈哈,就是name)和文本框name里面的值(yeah,就是``John``)。然后呢,到flask

instance中,request对象(如果不知道这是什么东西,看前文)里就会有所有这些有关请求的数据了。

辣么,辣么这跟from有毛线关系呢????

其实吧,form中的数据是flask从request(request是从environ构建的)中拿到并映射进form属性中的(映射过程发生在你实例化form的时候),这个过程我也不展开了。好吧,不知道有没有解释你

name = form.name.data

为什么会有数据的疑问。

我实在不想在打字了,好累噢!!!!!

吧,总结起来就是,HTTP utils将用户的raw request解析成符合wsgi规范的environ,然后flask

instance将environ丢到线程级的request

object里,在你实例化flask.ext.wtf.Form及其子类时,会从request object里解析并映射数据到form中。

关于读书的话,如果你觉得你实在看不明白,那可能是有关web底层一点的知识稍微欠缺,可以补补这块的知识,对于框架的处理机制,最好的办法是 看!!!源!!!!码!!!!!

看不懂就补基础,如此而已。

上面过程都是我信手打出来的,也好久没用flask了,写的时候也没查资料,如有bug或建议可以告诉我,以便我修改。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11384773.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-15
下一篇 2023-05-15

发表评论

登录后才能评论

评论列表(0条)

保存