我是一名新手程序员,在GAE上使用带有wtforms的瓶子,通过表格获取数据并列出数据。一切当前都在工作,但我的大多数观点使用非常相似的表单创建,发布和列表方法。我想要一种方法来简化混乱并减少我使用的代码量。
我见过三种可能的选择:
目前我有一些/ new / post / new / home等。
下面的相关Snipets代码: 的查看:
@app.route('/new/post', methods = ['GET', 'POST'])
@login_required
def new_post():
form = PostForm()
if form.validate_on_submit():
post = Post(title = form.title.data,
content = form.content.data,
hometest = form.hometest.data,
author = users.get_current_user())
post.put()
flash('Post saved on database.')
return redirect(url_for('list_posts'))
form.hometest.choices = [ (h.key.id(),h.homename)for h in Home.query()]
return render_template('new_post.html', form=form)
@app.route('/new/home',methods = ['GET','POST'])
def home_new():
form = HomeForm()
if form.validate_on_submit():
home = Home(homeid = int(form.homeid.data),
homename = form.homename.data)
home.put()
flash('Home saved on database')
return redirect(url_for('home'))
return render_template('new_home.html',form = form)
型号:
class Home(ndb.Model):
homeid = ndb.IntegerProperty(required=True)
homename = ndb.StringProperty(required=True)
hometest = ndb.IntegerProperty(required=True)
class Post(db.Model):
title = db.StringProperty(required = True)
content = db.TextProperty(required = True)
when = db.DateTimeProperty(auto_now_add = True)
author = db.UserProperty(required = True)
表单:
class PostForm(Form):
title = wtf.TextField('Title', validators=[validators.Required()])
content = wtf.TextAreaField('Content', validators=[validators.Required()])
hometest = wtf.SelectField(u'Home Name List', coerce=int,validators=[validators.optional()])
class HomeForm(wtf.Form):
homeid = TextField('ID of Home', [validators.Length(min=1, max=25)])
homename = TextField('Name of Home', [validators.Length(min=4, max=25)])
我在想一些更时尚的东西:
@app.route('/new/<whatsnew>', methods)
@mydecorator
def new_whatsnew:
Stuff specific to <whatsnew>
@app.route('/list/<whatsnew>', methods)
@mydecorator
def list_whatsnew
Stuff specific to <whatsnew>
当然,如果有更多可接受的方式(或没有办法解决这个问题)。我不是在寻找实际的代码,虽然一个例子会很好但是这是适当的设计方法吗?
答案 0 :(得分:2)
也许您需要一个可插拔的视图:
class FormView(View):
def __init__(self):
self.form_class = None
self.template = ''
self.success_url = ''
def on_validate(self, form):
pass
def on_invalidate(self, form):
pass
def dispatch_request(self):
form = self.form_class()
if form.validate_on_submit():
self.on_validate(form)
return redirect(self.success_url)
self.on_invalidate(form)
return render_template(self.template, form=form)
答案 1 :(得分:0)
感谢您的回答。我还是有点困惑。所以通过说我的帖子或家庭视图来使用它
def postview(FormView):
self.form_class = "HomeForm"
self.template = 'homelist.html' #without html # this is the form template?
self.success_url = url_for('homelist') #redirect goes here?
...从可插拔的视图文档here我对以下内容的使用感到困惑:
def dispatch_request(self):
context = {'objects': self.get_objects()}
return self.render_template(context)
在父类和下面的继承:
中def get_objects(self):
return User.query.all()
上下文是一个内置的Flask对象,但是将表单模板链接到formmodel的魔法,将它放入我的gae模型中,然后将你发送给另一个让我困惑的网址。
答案 2 :(得分:0)
我得到了:
文件 “/Volumes/320gb/Dropbox/Projects/git_projects/virtualenvs/gae/gae_take2000/flask/app.py” 第723行,在make_response中 提高ValueError('视图函数未返回响应')ValueError:视图函数未返回响应
添加新的SensorsView时出错。适用于所有其他几乎相同的视图。这是两个相同的。
显然这个错误是关于POST的,但我无法弄清楚它为什么会破坏。
<强>父类:强>
class FormView(View):
methods = ['GET', 'POST']
def __init__(self):
self.form_class = None
self.template = ''
self.success_url = ''
self.sfield = False
def on_validate(self, form):
pass
def on_invalidate(self, form):
pass
def on_sfield(self, form):
pass
def dispatch_request(self):
form = self.form_class()
if self.sfield:
form = self.on_sfield(form)
if request.method == 'GET':
return render_template(self.template, form=form)
if request.method == 'POST':
if form.validate_on_submit():
self.on_validate(form)
return redirect(url_for(self.success_url))
继承的ZoneView(完美运行):
class ZoneView(FormView):
def __init__(self):
FormView.__init__(self)
self.form_class = ZoneForm
self.template = 'new_zone.html'
self.success_url = 'ZoneList'
self.sfield = True
def on_sfield(self,form):
form.homekey.choices = [ (h.key.id(),h.homename)for h in Home.query()]
return form
def on_validate(self, form):
zone = Zone(zname = form.zname.data,
zonemac = form.zonemac.data) #, homekey = form.homekey.data
zone.put()
flash('Zone saved on database.')
app.add_url_rule('/new/zone', view_func=ZoneView.as_view('ZoneView'), methods = ['GET', 'POST'])
SensorsView(不使用错误):
class SensorsView(FormView):
def __init__(self):
FormView.__init__(self)
self.form_class = SensorForm
self.template = 'new_sensors.html'
self.success_url = 'SensorList'
self.sfield = True
def on_sfield(self,form):
form.zonekey.choices = [ (h.key.id(),h.zname)for h in Zone.query()]
return form
def on_validate(self, form):
sensor = Sensor(sensortype = form.sensortype.data,
pinmapping = form.pinmapping.data)
# zonekey = form.zonekey.data
sensor.put()
flash('Home saved on database.')
app.add_url_rule('/new/sensor', view_func=SensorsView.as_view('SensorsView'), methods = ['GET', 'POST'])
模板: ** new_zone:**
{% extends "base.html" %}
{% import 'macros.html' as mymacros %}
{% block content %}
<h1 id="">This is where your zone name will come into play</h1>
<form action="{{ url_for('ZoneView') }}" method="post" accept-charset="utf-8">
{{ form.csrf_token }}
<p>
{{mymacros.form_fields(form)}}
</p>
<p><input type="submit" value="Save Zone"/></p>
</form>
{% endblock %}
<强> new_sensors.html 强>
{% extends "base.html" %}
{% import 'macros.html' as mymacros %}
{% block content %}
<h1 id="">This is where your home name will come into play</h1>
<form action="{{ url_for('SensorsView') }}" method="post" accept-charset="utf-8">
{{ form.csrf_token }}
<p>
{{mymacros.myform_field(form.sensortype)}}
</p>
<p><input type="submit" value="Save post"/></p>
</form>
{% endblock %}
将代码剪切并粘贴并改为适合。非常相同。我不知道为什么它抱怨View功能。 我有没有看到错字?