0

我是一个新手程序员,在 GAE 上使用带有 wtforms 的烧瓶通过表单获取数据并列出数据。目前一切正常,但我的大多数观点都使用非常相似的表单创建、发布和列表方法。我想要一种方法来简化混乱并减少我使用的代码量。

我已经看到了三个潜在的选择:

  1. 来自 Flask 的可插入视图
  2. 只是一个简单的烧瓶装饰器
  3. 可能是方法视图?(见 1)。

目前我有一些 /new/post /new/home 等。

下面的相关代码片段: 视图:

@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>

当然,如果有更多可接受的方式(或没有办法解决这个问题)。我不是在寻找实际的代码,虽然一个例子会很好,但这是正确的设计方法?

4

3 回答 3

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)
于 2013-04-08T22:37:24.310 回答
0

我得到一个:

文件“/Volumes/320gb/Dropbox/Projects/git_projects/virtualenvs/gae/gae_take2000/flask/app.py”,第 723 行,在 make_response 中引发 ValueError('View function did not return a response') ValueError: View function did not返回响应

添加新的 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 功能。有没有我看不到的错字?

于 2013-04-16T19:54:25.003 回答
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?

...从此处的可插入视图文档中,我对以下内容的用法感到困惑:

def dispatch_request(self):
        context = {'objects': self.get_objects()}
        return self.render_template(context)

在父类和继承的类中:

def get_objects(self):
        return User.query.all()

上下文是一个内置的 Flask 对象,但是将表单模板链接到表单模型,将其放入我的 gae 模型,然后将您发送到另一个 url 的魔法仍然让我感到困惑。

于 2013-04-10T18:25:36.447 回答