I would like to store a list of user ids in content type's model and use them in some update subscriber to set some security settings based o the list of usernames. After some investigation how to implement it in relational database I came out with the following (inspired by kotti's tags and local groups) - see example code bellow.
My issue is that I can see list of principals in the add/edit form of the content type, I can select and save it .. all is saved to db and seems to by ok except that if I go to content type's edit form again nothing is selected inthe widget even if it's saved in db.. can somebody help me find what I'm doing wrong?
# === Example content model with field storing list of assigned users (assignees) ===
class Task(Content):
id = Column(
Integer,
primary_key=True
)
...
_assignees = relation(
TaskAssignees,
backref=backref('tasks'),
collection_class=list,
)
assignees = association_proxy(
'_assignees',
'assignee_id',
creator=TaskAssignees._manager_find,
)
# === Task assignees mapping model to store list of users assigned to task ===
class TaskAssignees(Base):
__tablename__ = 'task_assignees'
principal_id = Column(Integer, ForeignKey('
principals.id'), primary_key=True)
task_id = Column(Integer, ForeignKey('
tasks.id'), primary_key=True)
assignee = relation(Principal, backref=backref('assignee_of_tasks'))
assignee_id = association_proxy('assignee', 'id')
@classmethod
def _assignee_find(cls, assignee_id):
with DBSession.no_autoflush:
principal = DBSession.query(Principal).get(assignee_id)
return cls(assignee=principal)
# === Task schema definition for Add/Edit forms ===
class TaskSchema(ContentSchema):
assignees = colander.SchemaNode(
colander.Set(),
title=_('Assignees'),
widget=deferred_task_assignees_widget,
missing=[],
)
# === Task::assignees widget to let Editor (or whoever now)
# select users assigned to task ===
@colander.deferred
def deferred_task_assignees_widget(node, kw):
principals = Principal.query.all()
users = [(
user.id, user.title.encode('utf-8')) for user in principals]
widget = deform.widget.SelectWidget(values=tuple(users), multiple=True)
return widget