Python 使用Flask、WTForm、SQLAlchemy和Jinja2的完整多对一示例

Python 使用Flask、WTForm、SQLAlchemy和Jinja2的完整多对一示例,python,flask,flask-sqlalchemy,wtforms,flask-wtforms,Python,Flask,Flask Sqlalchemy,Wtforms,Flask Wtforms,这是我的HTML下拉菜单。该值是子表的主键 <select id="category" name="category"> <option selected value="__None"></option> <option value="1">Category Number One</option> <option value="2">Category Number Two</option> &l

这是我的HTML下拉菜单。该值是子表的主键

<select id="category" name="category">
   <option selected value="__None"></option>
   <option value="1">Category Number One</option>
   <option value="2">Category Number Two</option>
</select>
我试着做

cateogry_id=form.category.data
cateogry_id=form.category.value

那不是很好吗

我想出来了!这是我的解决办法。希望这篇文章能帮助下一个人

解决方案是让扩展为您完成工作!下面是一个工作示例,WT使用Flask、WTForm、sqlalchemy和Jinja2形成sqlalchemy扩展。简而言之,您不需要担心孩子id,因为扩展自动处理它。这意味着,在一对多关系中处理SQLAlchemy父模型和子模型时,只需处理父模型

模型

首先,确保你的模型和关系是正确的。请注意,在我的示例中,关系是如何定义的,并且模型的init仅具有类别。。。不是CATEGORY_ID。我的错误是认为我应该填充模型的CATEGORY_ID字段。不。分机为您做这件事。事实上,如果你试着像我那样手动操作,它根本不会工作

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(80))
    url = db.Column(db.String(120))
    body = db.Column(db.Text)
    create_date = db.Column(db.DateTime)
    pub_date = db.Column(db.DateTime)
    pub_status = db.Column(db.Text(80))
    author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    author = db.relationship('User',
                             backref=db.backref('posts', lazy='dynamic'))
    category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
    category = db.relationship('Category',
                               backref=db.backref('posts', lazy='dynamic'))

    def __init__(self, title, body, category, pub_date=None):
        self.title = title
        self.body = body
        if pub_date is None:
            pub_date = datetime.utcnow()
        self.category = category
        self.pub_date = pub_date

    def __repr__(self):
        return '<Post %r>' % self.title

class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    description = db.Column(db.String(250))

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return self.name
现在,烧瓶路由和视图逻辑。。。请再次在帖子中注意无类别标识!仅限类别

路由/视图

# create new post
@app.route('/admin/post', methods=['GET', 'POST'])
@login_required  # required for Flask-Security
def create_post():
    form = PostForm()
    if form.validate_on_submit():
        post = Post(title=form.title.data, pub_date=form.pub_date.data,
                    body=form.body.data, category=form.category.data)
        db.session.add(post)
        db.session.commit()
        flash('Your post has been published.')
        return redirect(url_for('admin'))
    posts = Post.query.all()
    return render_template('create_post.html', form=form, posts=posts)
最后是模板。猜猜看,我们只生成form.category字段

模板

  <form action="" method=post>
  {{form.hidden_tag()}}
    <dl>
      <dt>Title:
      <dd>{{ form.title }}
      <dt>Post:
      <dd>{{ form.body(cols="35", rows="20") }}
      <dt>Category:
      <dd>{{ form.category }}

    </dl>
    <p>
      <input type=submit value="Publish">
  </form>

{{form.hidden_tag()}}
标题:
{{form.title}}
职位:
{{form.body(cols=“35”,rows=“20”)}
类别:
{{form.category}}


结果。。。此解决方案正确地使用类别模型作为查找表,并通过将类别PK整数写入Posts Category_Id字段来正确关联Post行。是啊

我解决了这个问题。。。我使用的是WT Forms QuerySelectField,所以我的错误是认为我需要将category_id字段添加到jija2模板中。。。。WTF扩展为您处理所有这些。所以您所要做的就是担心类别字段。这适用于视图、模板和模型。感谢分享。在wtforms文档中确实需要更多这样的例子。
# create new post
@app.route('/admin/post', methods=['GET', 'POST'])
@login_required  # required for Flask-Security
def create_post():
    form = PostForm()
    if form.validate_on_submit():
        post = Post(title=form.title.data, pub_date=form.pub_date.data,
                    body=form.body.data, category=form.category.data)
        db.session.add(post)
        db.session.commit()
        flash('Your post has been published.')
        return redirect(url_for('admin'))
    posts = Post.query.all()
    return render_template('create_post.html', form=form, posts=posts)
  <form action="" method=post>
  {{form.hidden_tag()}}
    <dl>
      <dt>Title:
      <dd>{{ form.title }}
      <dt>Post:
      <dd>{{ form.body(cols="35", rows="20") }}
      <dt>Category:
      <dd>{{ form.category }}

    </dl>
    <p>
      <input type=submit value="Publish">
  </form>