Создание динамической формы с помощью 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. Загвоздка в том, что мне нужно определить тип поля для рендеринга для каждого Formfield. Поэтому мне также нужно обработать fieldtype в какой-то момент.
Я думаю, что решением было бы каким-то образом передать form_id функции в моем классе формы.
Я понятия не имею, как это сделать или где искать решение.
любая помощь была бы очень признательна!
1 ответов
Я думаю, что мне удалось создать динамические формы с идеей отсюда https://groups.google.com/forum#!тема/wtforms/cJl3aqzZieA
вы должны создать динамическую форму в функции просмотра, получить поле формы, которое вы хотите получить, и повторять каждое поле для создания этого объекта формы. Я использовал для fieldtypes простой текст вместо целочисленных значений. Поскольку это кажется легким для чтения на уровне кода.
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
для простой формы визуализации шаблона jinja формы.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 %}