我通过Flask.WTF扩展使用带有Flask的WTForms.不过,这个问题不是Flask特有的.
WTForms包括FieldList字段列表的字段.我想用它来制作一个用户可以添加或删除项目的表单.这将需要某种Ajax框架来动态添加小部件,但WTForms文档没有提及它.
我是新的python web-dev,我有flask + wtforms应用程序.我可以在login()中看到用户对象存储为
if user:
if user.verify_password(form.password.data):
flash('You have been logged in')
user.logins += 1
db.session.add(History(user.uid))
db.session.commit()
session['user'] = user
Run Code Online (Sandbox Code Playgroud)
现在我想要检索用户
if 'user' in session:
User=session.get('user')
print User.nickname ###<< how to retrieve specific object member?
Run Code Online (Sandbox Code Playgroud)
它失败了,消息如下:
Instance <User at 0x8e5a64c> is not bound to a Session; attribute refresh operation cannot proceed
Run Code Online (Sandbox Code Playgroud) 首先,我是python和Flask的新手,所以如果我的问题很愚蠢,我很抱歉.我搜索它但从未找到答案(我猜这应该是一个"简单"的答案).
我想在我的网站上添加一个联系页面,我找到了这个教程,所以我跟着它.一切正常,直到表单验证.我只使用Required,form.validate()总是返回false.如果我不触摸我的代码,并删除表单类中的每个Required,它工作正常,form.validate()返回true.
我真的不明白为什么,我读了很多应该使用validate_on_submit(),但是如果我使用它我会收到错误:*'ClassName'对象没有属性'validate_on_submit'*
这是代码的相关部分:
Index.py
@app.route('/contact', methods=['GET','POST'])
def contact():
form = ContactForm()
if request.method == 'POST':
if form.validate() == False:
flash('All Fields are required.')
return render_template('contact.html', form=form)
else:
return 'Form posted'
elif request.method == 'GET':
return render_template('contact.html', form=form)
Run Code Online (Sandbox Code Playgroud)
forms.py
from wtforms import Form, TextField, TextAreaField, SubmitField, validators,ValidationError
class ContactForm(Form):
name = TextField("Name", [validators.Required()])
email = TextField("Email")
subject = TextField("Subject")
message = TextAreaField("Message")
submit = SubmitField("Send")
Run Code Online (Sandbox Code Playgroud)
contact.html
<div id="contact">
{% for …Run Code Online (Sandbox Code Playgroud) 我不太确定如何解决这个问题.我希望我能到达那里.
例如,我在一个页面上有一个充满地址的表.这些是动态的(可以是5或10或任何其他计数).我希望有可能在一个页面上编辑它们.
我的方法是创建wtforms表单编辑一个地址,并乘以它在Jinja2的for loop和附加到HTML propertys name并id在
loop.index0从itereation,这样我就可以提取人工数据的每一行,并把它放回我的形式,当我想评估它.
因此,此示例的表单将是:
class AdressForm(Form):
name = TextField()
Run Code Online (Sandbox Code Playgroud)
所以现在我的模板aproach看起来如下(分解为一个输入字段):
{% for address in addresses %}
{{ forms.render_field(addressform.name, id = "name_" ~ loop.index0,
name = "name_" ~ loop.index0, value = address.name) }}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)
(forms.render_field只是一个宏,用于指定wtforms的字段函数的正确类.就像它们在许多教程中使用的那样)
所以这不起作用,因为你不能name手动将参数传递给字段函数,因为wtforms name从初始Form的variblename创建html-paramter.
那么有没有办法将前缀或后缀添加到我想要呈现的表单的名称.或者这是一个XY问题,我的方法总是错误的.
或者我自己一点都做(我真的试图避免这种情况)
例如,调用WTForms字段对象会生成渲染字段,并且任何参数都将被视为属性.
form.field(attribute='value')
Run Code Online (Sandbox Code Playgroud)
会返回类似的东西
<input attribute='value'>
Run Code Online (Sandbox Code Playgroud)
如何添加HTML5自定义数据属性,例如包含连字符的data-provide,使它们在python中不可解析为单个关键字参数?
我正在尝试使用WTForms.SelectMultipleField来管理表单上的一些动态选择但是我遇到了一些困难,因为它在提交验证之前被修改为客户端.
基本上我有两个SelectMultipleField选项:
class MyForm(Form):
assigned = SelectMultipleField('Assigned', choices=[])
available = SelectMultipleField('Available', choices=[('1','1'),('2','2')])
Run Code Online (Sandbox Code Playgroud)
我正在使用Flask渲染Jinja2模板,如下所示:
@app.view("/myview", methods=['GET','POST'])
def myview():
form = MyForm(request.form)
if request.method == 'POST' and form.validate():
return render_template("success.html")
else:
return render_template("index.html", form=form)
Run Code Online (Sandbox Code Playgroud)
在我的模板中,我有这个:
<script type="text/javascript">
function assign_object() {
return !$('#available option:selected').remove().appendTo('#assigned');
};
function unassign_object() {
return !$('#assigned option:selected').remove().appendTo('#available');
}
$(document).ready( function() {
$('#available').dblclick( assign_object );
$('#assigned').dblclick( unassign_object );
});
</script>
<form action="/myview" method="post" name="assign_objects">
{{ render_field(form.a) }}
{{ render_field(form.b) }}
<input type="submit" value="Assign" name="assign_button"/>
</form>
Run Code Online (Sandbox Code Playgroud)
基本上所有这些都按预期工作; 双击未分配列表中的项目会将其移动到指定的列表.问题是提交表单进行验证时,因为"已分配"字段上的.choices属性最初为"[]",但仍然是"[]"而不是我们给出的新选项列表.
有谁知道这样做的好方法?我想我可以覆盖表单pre_validate()函数并更新assigned.choices以包含"可用"列表中的所有值,但这感觉不对"并且可以用来从客户端提交随机值 - 提交方面. …
对于我的生活,我无法弄清楚如何使用WTForms预填充BooleanField.我有一个名为"活跃"的字段.它默认为未选中,并且不是必需的.所以我把它设置成......
class QuestionForm(Form):
question = TextField('Question', [validators.Required()])
slug = TextField('Slug', [validators.Required()])
active = BooleanField('Active')
Run Code Online (Sandbox Code Playgroud)
然后我有一个编辑页面,我在其中显示我要编辑的"问题"的表单.
{{ form.question.label }}
{{ form.question(value=q.question) }}
{{ form.active(value=q.active) }} Show this question?
Run Code Online (Sandbox Code Playgroud)
如果'active'为True,我希望BooleanField(复选框)具有'checked'属性.如果错,不要.但我甚至无法弄清楚如何使复选框具有检查状态,在渲染表单时,更不用说条件部分了.
唯一的方法,我能够让它显示检查是我在定义表单时添加default = True.但那不是我需要的.
我尝试使用'default','initial','value','selected',同时渲染表单没有运气.我搜索了文档和谷歌.我想我错过了什么!:)
UPDATE
这是我的观点.也许是问题?
@mod.route('/q/<slug>/edit', methods = ['GET', 'POST'])
def edit(slug):
form = QuestionForm(request.form, csrf_enabled=False)
q = Question.query(Question.slug==slug).get()
if request.method=='POST':
if form.validate_on_submit():
q.question = form.data.get('question')
q.slug = form.data.get('slug')
q.active = form.data.get('active')
q.put()
return redirect('/questions')
return render_template('questions/edit.html', form=form, q=q)
Run Code Online (Sandbox Code Playgroud) 这是我的代码:
class CreateUser(Form):
username = StringField('Username', [
validators.Regexp('\w+', message="Username must contain only letters numbers or underscore"),
validators.Length(min=5, max=25, message="Username must be betwen 5 & 25 characters")
])
password = PasswordField('New Password', [
validators.DataRequired(),
validators.EqualTo('confirm', message='Passwords must match')
])
confirm = PasswordField('Repeat Password')
Run Code Online (Sandbox Code Playgroud)
所以问题存在于第3行.我希望用户名只是字母数字字符.由于某种原因,这个正则表达式只检查第一个字符.有没有理由说+符号在这里不起作用?谢谢.
我有一个Web应用程序,它由位于同一服务器上的REST API支持.假设我有一个Task可访问的资源/api/task/<task_id>和一个网页/create-task,它基本上只是一个创建任务的表单.有几种方法可以做到:
a)使用Javascript与REST API通信(不想这样做)
b)直接在数据库中创建对象
@app.route('/create-task', methods=['POST'])
def create_task(self):
# create an object
try:
task = Task(request.form)
except:
# handle errors and put them to form
pass
# save it into db
task.save()
Run Code Online (Sandbox Code Playgroud)
c)使用requests库调用REST API
@app.route('/create-task', methods=['POST'])
def create_task(self):
# send request to REST API
r = requests.post(url_for('api.task', _external=True), json=request.form.data)
if r.status_code != 200:
# handle errors and put them to form
pass
Run Code Online (Sandbox Code Playgroud)
您认为哪种选择是最佳做法?考虑与错误处理和表单相关的问题.
有关的奖金问题flask-restful.假设我已经建立了一个使用flask-restful构建的工作API,并希望使用选项b).我可以以某种方式使用TaskResource.post这样做吗?
提交后如何从 WTForms 表单中获取数据?我想获取在表单中输入的电子邮件。
class ApplicationForm(Form):
email = StringField()
@app.route('/', methods=['GET', 'POST'])
def index():
form = ApplicationForm()
if form.validate_on_submit():
return redirect('index')
return render_template('index.html', form=form)
Run Code Online (Sandbox Code Playgroud)
class ApplicationForm(Form):
email = StringField()
@app.route('/', methods=['GET', 'POST'])
def index():
form = ApplicationForm()
if form.validate_on_submit():
return redirect('index')
return render_template('index.html', form=form)
Run Code Online (Sandbox Code Playgroud)