0

为糟糕的标题道歉。

我正在使用 Flask 和 SQLAlchemy 建立一个网站。我想要一个可用于所有内容类型的标签列表。我正在使用 sqlite3 作为我的开发数据库。

使用html表单输入数据后,只有标签没有被保存到数据库中。我不确定弱点在哪里?我不知道我在概念上是否有关于 SQLAlchemy 如何处理继承、将参数传递给子类和/或多对多关系的问题。我真的很感激任何关于如何改进模型的主题或建议的明确性。

这是代码:

我有一个标签和内容之间的多对多关系的关联表:

tagging_association = Table('tagging', Model.metadata,
    Column('content_id', Integer, ForeignKey('content.id')),
    Column('tag_id', Integer, ForeignKey('tags.id'))
)

我已经设置了一个 Content 类:

class Content(Model):
    ''' 
    The base class for all content types.
    '''
    __tablename__ = 'content'
    id = Column(Integer, primary_key=True)
    tag = relationship('Tag', secondary='tagging', backref='content')
    type = Column(String(50))

    __mapper_args__ = { 
        'polymorphic_identity':'content',
        'polymorphic_on':type
    }   

所有内容类型都是 Content 的子类,使用 SQLAlchemy 的 Joined Table Inheritance:

class Entry(Content):
    '''The database model for blog-like entries on the homepage.'''
    __tablename__ = 'entries'
    id = Column(Integer, ForeignKey('content.id'), primary_key=True)
    title = Column(String(200))
    body = Column(String)

    __mapper_args__ = { 
        'polymorphic_identity':'entries',
    }   

    # Want to pass a single tag first, just to get it to work. Is this how would I do that?
    def __init__(self, title, body, *args, **kwargs):
        super(Entry, self).__init__(*args, **kwargs)
        self.title = title
        self.body = body

和标签类:

class Tag(Model):
    '''Tag database model.'''
    __tablename__ = 'tags'
    id = Column(Integer, primary_key=True)
    tag = Column(String(30), nullable=False, unique=True)

    def __init__(self, tag):
        self.tag = tag 

这是我的 WTForms 课程:

class EntryForm(Form):
    title = TextField('Title', validators=[Required()])
    body = TextAreaField('Body', validators=[Required()])
    tags = TextField('Tags') 
    submit = SubmitField('Submit')

这是我获取表单数据并将其添加到数据库的地方:

@mod.route('/add_entry/', methods=['GET', 'POST'])
@requires_admin
def add_entry():
    form = EntryForm()
    if form.validate():
        entry = Entry(form.title(), form.body(), form.tags())
        form.populate_obj(entry)
        db_session.add(entry)
        db_session.commit()
        return redirect(url_for('general.index'))
    return render_template('general/add_entry.html', form=form)
4

1 回答 1

1

如果您在上面显示的是实际代码,您可以看到您的关系被命名为tag( tag = relationship(...),但在EntryForm您的TextField属性中被称为tags。所以您的tag关系永远不会设置,因此永远不会保存。设置到该字段tags的内容将被忽略。我假设您只需要将 重命名Content.tagContent.tags.

上面应该回答为什么它没有保存的问题,但是如果你只是重命名字段,这不会解决你的问题。您需要编写正确处理标签的代码:

  • 将标记文本分配给内容时,您需要:
    1. 看看这个标签是否tag已经存在。
    2. 如果是,请加载它。
    3. 如果没有,请创建它
    4. 将找到/创建的标签附加到Content.tags

有关类似问题,请参阅在 SQLAlchemy 中以多对多关系插入数据的答案,让您了解要做什么以及如何完成。

于 2012-05-10T07:10:30.170 回答