网站标记:SQLAlchemy继承,将参数传递给超类,以及多对多关系

时间:2012-05-09 19:33:27

标签: sqlalchemy flask

为可怕的头衔道歉。

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

使用html表单输入数据后,只有标记没有保存到db。我不确定弱点(s?)在哪里。我不知道我是否在概念上有一些关于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

Tag类:

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')

这是我获取表单数据并将其添加到db:

的位置
@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)

1 个答案:

答案 0 :(得分:1)

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

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

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

查看Inserting data in Many to Many relationship in SQLAlchemy对类似问题的回答,了解如何操作以及如何完成。