Создание динамической формы с помощью flask-wtf и sqlalchemy
У меня есть веб-приложение, которое позволяет пользователям создавать свои собственные поля для последующего отображения в форме.
У меня есть модель Formfield, такая как:
class Formfield(db.Model):
id = db.Column(db.Integer, primary_key = True)
form_id = db.Column(db.Integer, db.ForeignKey('formbooking.id'))
label = db.Column(db.String(80))
placeholder_text = db.Column(db.String(80))
help_text = db.Column(db.String(500))
box_checked = db.Column(db.Boolean, nullable = True, default = False)
options = db.Column(db.String) # JSON goes here?
answer = db.Column(db.String)
required = db.Column(db.Boolean, nullable = False, default = False)
order = db.Column(db.Integer)
fieldtype = db.Column(db.Integer)
Что я использую для представления поля, независимо от вида (флажок, ввод, больше в будущем).
Как вы можете видеть, каждое поле имеет отношение FK к form_id.
Я пытаюсь создать динамическую форму для данного form_id.
Загвоздка в том, что мне нужно определить тип поля для визуализации для каждого поля формы.
Так что мне тоже нужно обработайте тип поля в какой-то момент.
Я думаю, что решением было бы каким-то образом передать form_id функции в моем классе Form.
Я понятия не имею, как это сделать и где искать решение.
Любая помощь будет очень признательна!
1 ответ:
Я думаю, что мне удалось создать динамические формы с идеей отсюда https://groups.google.com/forum/#! topic/wtforms/cJl3aqzZieA
Вы должны создать динамическую форму в функции представления, получить поле формы, которое вы хотите получить, и повторить каждое поле, чтобы построить этот объект формы. Я использовал для типов полей простой текст вместо целых значений. Так как он кажется легко читаемым на уровне кода.
class FormView(MethodView): def get(self): class DynamicForm(wtforms.Form): pass dform = main.models.Form.objects.get(name="name2") name = dform.name for f in dform.fields: print f.label setattr(DynamicForm , f.label, self.getField(f)) d = DynamicForm() # Dont forget to instantiate your new form before rendering for field in d: print field # you can see html output of fields return render_template("customform.html", form=d) def getField(self, field): if field.fieldtype == "text": return TextField(field.label) if field.fieldtype == "password": return PasswordField(field.label) # can extend if clauses at every new fieldtypeДля простой формы render jinja template 'формы.html '
{% macro render(form) -%} <fieldset> {% for field in form %} {% if field.type in ['CSRFTokenField', 'HiddenField'] %} {{ field() }} {% else %} <div class="form-group {% if field.errors %}error{% endif %}"> {{ field.label }} <div class="input"> {% if field.name == "body" %} {{ field(rows=10, cols=40) }} {% else %} {{ field() }} {% endif %} {% if field.errors or field.help_text %} <span class="help-inline"> {% if field.errors %} {{ field.errors|join(' ') }} {% else %} {{ field.help_text }} {% endif %} </span> {% endif %} </div> </div> {% endif %} {% endfor %} </fieldset> {% endmacro %}И customform.html выглядит так
{% extends "base.html" %} {% import "forms.html" as forms %} {% block content %} {{ forms.render(form) }} {% endblock %}
Comments