Динамическая генерация форм на основе БД в Flask

#flask #flask-sqlalchemy #flask-wtforms #wtforms

#flask #flask-sqlalchemy #flask-wtforms #wtforms

Вопрос:

Недавно я решил создать форму создания формы в веб-приложении Flask. После поиска по созданию формы найдены классы Formfield, FieldList в формах flask wtf, и я могу создать форму с этими классами. но это не дает того, что я хочу.

Во-первых, я собираюсь создать форму создания формы, которая поможет мне создать форму и поля в интерфейсе управления.

Во-вторых, я хочу иметь возможность добавлять поля, а не поля одного типа, разного типа, такие как (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 со страницы управления. И это поможет в любое время создавать новую форму и связывать поля с формой. И в Интернете я все еще не нашел создание формы в стиле these для Flask, почти все они создают dynamic for с полями того же типа

Есть идеи?

Комментарии:

1. Добро пожаловать в Stack Overflow! Шаблон, на который вы ссылаетесь, называется EAV или [Entity-Attribute-Value]() . Здесь довольно сложно дать индивидуальный совет, поскольку для комбинации WTForms и SQLAlchemy практически нет существующих решений. Однако для Django существует eav-django , который вы могли бы использовать для вдохновения.

2. @NickShebanov спасибо за ваш ответ, вы перенаправили меня на правильный адрес. EAV — это тот, который мне нужно реализовать. Еще раз спасибо!

Ответ №1:

Последние пару недель я искал, как динамически создавать форму flask на основе моделей

И @nick-shebanov перенаправил меня на другой подход к подслушиванию, который действительно сложно реализовать. Я пробовал 🙂

И решите создать форму на основе словаря и намерены заполнить связанные атрибуты из модели и передать ее в форму как словарь.

Что я сделал до сих пор;

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

Теперь я вижу, что все мои поля были отображены, включая скрытое поле. Когда я заполняю форму и отправляю данные, я могу их захватить.

Но все же я еще не смог реализовать сохранение захваченных данных в базе данных, например, в стиле вертикального моделирования БД

Вот мой простой подход к моделированию БД

смотрите изображение здесь

Есть ли предложения?