我正在尝试在Flask中创建任务管理应用程序,并且遇到了以下问题。
我有3个模型,User
,Task
和Project
。我希望用户能够创建任务并将其分配给其他用户。这需要在Task
和User
模型之间进行多个联接。
以前,在尝试实现此功能之前,我有一个从User
到Task
的一对多关系,这种关系很好,并且下面有两个原始模型。
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=True )
email = db.Column(db.String(120), unique=True, nullable=True)
password_hash = db.Column(db.String(128))
tasks = db.relationship('Task', backref='author', lazy='dynamic') # one user has many tasks
projects = db.relationship('Project', backref='author', lazy='dynamic') # one user has many projects
class Task(UserMixin, db.Model):
__tablename__ = 'tasks'
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.String(128))
due = db.Column(db.DateTime, index=True)
done = db.Column(db.Boolean, default=False)
author_id = db.Column(db.Integer, db.ForeignKey('users.id')) # task belongs to user
project_id = db.Column(db.Integer, db.ForeignKey('projects.id')) # task belongs to project
在SQL Alchemy documentation之后,我向Task添加了assigned_to_id
列,并向User添加了assigned_tasks
列。
我的模型如下:
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=True )
email = db.Column(db.String(120), unique=True, nullable=True)
password_hash = db.Column(db.String(128))
tasks_id = db.Column(db.Integer, db.ForeignKey('tasks.id'))
assigned_tasks_id = db.Column(db.Integer, db.ForeignKey('tasks.id'))
tasks = db.relationship('Task', foreign_keys="User.tasks_id", backref='author') # one user has many tasks
assigned_tasks = db.relationship('Task', foreign_keys="User.tasks_id", backref='assigned_to') # one user has many tasks
projects = db.relationship('Project', backref='author', lazy='dynamic') # one user has many projects
class Task(UserMixin, db.Model):
__tablename__ = 'tasks'
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.String(128))
due = db.Column(db.DateTime, index=True)
done = db.Column(db.Boolean, default=False)
author_id = db.Column(db.Integer, db.ForeignKey('users.id')) # task belongs to user
assigned_to_id = db.Column(db.Integer, db.ForeignKey('users.id'))
project_id = db.Column(db.Integer, db.ForeignKey('projects.id')) # task belongs to project
由于我对需要分配的任务或需要分配任务的用户没有任何限制,因此我认为我应该能够像以前一样继续创建用户和任务。但是现在,当我尝试与作者创建任务时,出现错误。
>>> u = User(email='test@example.com', password='password')
>>> t = Task(body='New Task', author=u)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "<string>", line 4, in __init__
File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/orm/state.py", line 417, in _initialize_instance
manager.dispatch.init_failure(self, args, kwargs)
File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py", line 66, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/util/compat.py", line 249, in reraise
raise value
File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/orm/state.py", line 414, in _initialize_instance
return manager.original_init(*mixed[1:], **kwargs)
File "/Users/Jasmine/projects/flask/tasky/app/models.py", line 67, in __init__
super(Task, self).__init__(**kwargs)
File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/ext/declarative/base.py", line 700, in _declarative_constructor
setattr(self, k, kwargs[k])
File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/orm/attributes.py", line 229, in __set__
instance_dict(instance), value, None)
File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/orm/attributes.py", line 1040, in set
given, wanted))
TypeError: Incompatible collection type: User is not list-like
我可能误解了这里的错误,但是在我看来,现在每个任务都期望有多个作者。我该如何保持一对多的关系,以便每个任务只期望一个作者呢?
答案 0 :(得分:0)
由于我的声誉,我无法添加评论,但 One-to-many Flask | SQLAlchemy
这里公认的答案应该会对您有所帮助。 还有...
>>> u = User(email='test@example.com', password='password')
>>> t = Task(body='New Task', author=u)
作者变量在Task类中不存在,而在User类中不存在
您需要将用户添加到任务。 您可能想查看一下代码,这些类之间的关系似乎不正确。那或者我弄错了。