首页 > 解决方案 > Flask 中基于 DB 的动态表单生成

问题描述

最近我决定在 Flask Web 应用程序中创建表单创建表单。在搜索表单创建后,在烧瓶 wtf 表单中找到 Formfield、FieldList 类,我可以使用这些类创建表单。但它没有提供我想要的。

首先-我将创建一个表单创建表单,它将帮助我在管理界面上创建表单和字段。

其次-我希望能够添加字段,而不是相同类型的字段,所有不同的类型,例如(booleanField、StringField、IntegerField、DateTimeField 等),因为在表单中可能有不同类型的字段用于特定原因。

第三-我想在我想在我的视图中使用时检索此表单

在数据库模型方面;

class Form(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.StringField)
    fields = db.relationship('FormFields', backref='forms', lazy=True)

class FormFields(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.StringField)
    field_type = db.Column(db.StringField)
    form_id = db.Column(db.Integer, db.ForeignKey('forms.id'), nullable=False)

StrinField、BooleanField、TextField 等的其他表应该连接到这个字段模型,当我在这个创建的表单上保存数据时,这些数据应该保存在正确的表中

我之所以搜索这个,是因为我不想硬编码代码中的表单和字段,当我需要新的表单或字段时,我不想更新代码本身,它应该在数据库上动态更新。

我想从管理页面使用基于 sqlalchemy 的表单创建。这将有助于随时创建新表单并将字段与表单相关联。而且在互联网上我仍然没有找到为 Flask 创建这些样式的表单,几乎所有这些都为相同类型的字段创建动态

有任何想法吗?

标签: flaskflask-sqlalchemyflask-wtformswtforms

解决方案


过去几周我在搜索如何基于模型创建动态烧瓶表单

@nick-shebanov 已将我重定向到另一种方法 EAV 实施,这真的很难实施。我试过了 :)

并决定基于字典创建表单,并打算从模型中填充相关属性并将其作为字典传递给表单。

到目前为止我做了什么;

# app.py file
from flask_wtf import Form
from flask import Flask, render_template, request, flash
from flask_wtf import FlaskForm
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from wtforms import TextField, IntegerField, HiddenField, StringField, TextAreaField, SubmitField, RadioField,SelectField
from wtforms import validators, ValidationError
    
app = Flask(__name__)
app.secret_key = 'secret123'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///sqlite.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
migrate = Migrate(app, db)

# form class with static fields
class DynamicForm(FlaskForm):
    form_type = HiddenField(default='FormType', render_kw={ 'type':'hidden' })
    # name = StringField()    

@app.route('/', methods=['GET', 'POST'])
def index():
    fields = {
        'username': 'Username',
        'first_name': 'Fisrt Name',
        'last_name': 'Last Name',
        'email': 'Email',
        'mobile_phone': 'Mobile Phone'
    }

    for key, value in fields.items():
        setattr(DynamicForm, key, StringField(value))

    form = DynamicForm()

    if request.method == 'POST':
        # print(dir(request.form))
        # print(request.form)
        dict = request.form.to_dict()
        # print(dict.keys())
        print(request.form.to_dict())
    return render_template('index.html', form=form)

if __name__ == '__main__':
   app.run(debug = True)


# index.html template
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <form method="POST">
        {{ form.csrf_token }}
        {{ form.form_type }}

        {% for field in form if field.name != 'csrf_token' %}
          {% if field.name != 'form_type' %}
            <div>
              {{ field.label() }}
              {{ field() }}

              {% for error in field.errors %}
                <div class="error">{{ error }}</div>
              {% endfor %}
            </div>
          {% endif %}
        {% endfor %}

        <input type="submit" value="Go">
    </form>
  </body>
</html>

现在我可以看到我的所有字段都已渲染,包括隐藏字段。当我填写表格并发布数据时,我可以捕获它。

但是我仍然没有实现像垂直数据库建模风格那样将捕获的数据保存到数据库中

这是我的数据库建模的简单方法

在这里看图片

有建议吗?


推荐阅读