Вот как я бы это сделал:
Создайте две новые таблицы, одну для полей и одну для ответов.Сделайте ответ дочерним как для вопроса (пользовательское поле), так и для исходного элемента.Пользователи могут добавлять поля, добавляя строки в таблицу полей, и вы можете получать ответы на все настраиваемые поля всякий раз, когда извлекаете исходный элемент:
class CustomField(Base):
__tablename__ = 'custom_fields'
id = Column(Integer, primary_key=True)
name = Column(String(128)) # internal name in this case
title = Column(Text) # Text of field label
class CustomResponse(Base):
__tablename__ = 'custom_responses'
id = Column(Integer, primary_key=True)
item_id = Column(Integer, ForeignKey('items.id'))
item = relationship('Item', backref='custom_responses')
custom_field_id = Column(Integer, ForeignKey('custom_fields.id'))
custom_field = relationship('CustomField') # put backref here if needed
value = Column(Text) # Actual answer
Вы можете даже предоставить инструкции для всего, что вы используете длянарисуйте форму, поместив столбец widget = Column(...)
в таблицу custom_fields или любые другие параметры / инструкции.Если вы хотите, чтобы каждое настраиваемое поле было доступно только одному элементу, дублируйте столбец item_id
и отношение item
в модели CustomField.
Нет смысла пытаться принудительно поместить все данные в одну строку;пусть sqlalchemy позаботится об отношениях.В этом случае вы можете получить все вопросы и ответы по настраиваемым полям через отношения:
Если i = Item()
, то i.custom_responses
вернет список всех завершенных объектов CustomResponse, связанных с этим элементом, и для каждого custom_response
, вы можете получить вопрос с custom_response.custom_field
.