I have a many-to-many relationship between objects User
and Groups
. I have an association object called Attends
which contains the extra field role
. I want to reduce the verbosity of the association object relationship by using association proxy. Unfortunately, the documentation was not very clear on how to explicitly add the extra field role
when I am appending a new user to a group.
Group class
class Group(db.Model):
__tablename__ = 'group'
gid = db.Column(db.Integer, primary_key=True, autoincrement=True)
oid = db.Column(db.Integer, db.ForeignKey('organization.oid'), nullable=False)
start_time= db.Column(db.DateTime, nullable=False)
end_time = db.Column(db.DateTime, db.CheckConstraint('end_time > start_time'), nullable=False)
location = db.Column(db.String, nullable=False)
description = db.Column(db.Text)
organization = db.relationship('Organization', back_populates='groups')
#many-to-many db.relationship with users
registered_users = association_proxy('user_groups', 'user')
#one to many db.relationship with tags
tags = db.relationship('Tag', back_populates='group')
def add_user(self, user, role):
if not self.has_user(user):
self.registered_users.append(Attend(user, self, role)) <-- error
else:
raise ValueError('user %s already exists', user)
Attend class
class Attend(db.Model):
__tablename__ = 'attend'
uid = db.Column(db.Integer, db.ForeignKey('user.uid'), primary_key=True)
gid = db.Column(db.Integer, db.ForeignKey('group.gid'), primary_key=True)
user_role = db.Column(db.Enum(*GroupRoles.roles, name='role'))
group = db.relationship('Group',
backref=db.backref('user_groups', cascade='all, delete-orphan'))
user = db.relationship('User')
def __init__(self, user, group, role):
self.user = user
self.group = group
self.user_role = role
I receive the following error when executing add_user
method:
def _create(self, value):
> return self.creator(value)
E TypeError: __init__() missing 2 required positional arguments: 'group' and 'role'
user_groups
should be aa list of Attend
objects (ie a relationship to Attend
), and registered_users
should be a list of User
objects. When you append to registered_users
, you need to let the association_proxy
know how to construct the corresponding Attend
object in user_groups
( docs ):
registered_users = association_proxy('user_groups', 'user',
creator=lambda u: Attend(user=u, user_role='some_default_role'))
Note: SQLAlchemy doesn't know what role
is, so you'll need to provide a default value. It does know what the group should be, by virtue of the user_groups
relationship being on Group
. If you want to be able to do add_user(user, role)
, you can simply append directly to the relationship yourself:
def add_user(self, user, role):
if not self.has_user(user):
self.user_groups.append(Attend(user=user, user_role=role))
else:
raise ValueError('user %s already exists', user)
Note that this assumes you change your Attend
class to use the default constructor.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.