0

ひどいタイトルで申し訳ありません。

Flask と SQLAlchemy を使用して、Web サイトをセットアップしています。すべてのコンテンツ タイプで使用できるタグのリストが必要です。開発データベースに 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
    }   

すべてのコンテンツ タイプは、SQLAlchemy の Joined Table Inheritance を使用した Content のサブクラスです。

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

フォームデータを取得してデータベースに追加する場所は次のとおりです。

@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.tagするだけでよいと仮定しますContent.tags

上記は保存されない理由の質問に答えるはずですが、フィールドの名前を変更しただけでは問題は解決しません。タグを適切に処理するコードを記述する必要があります。

  • タグ テキストがコンテンツに割り当てられている場合は、次のものが必要です。
    1. これを持つタグがtag既に存在するかどうかを確認してください。
    2. ある場合は、ロードします。
    3. そうでない場合は、作成します
    4. found/created タグをContent.tags

同様の問題については、SQLAlchemy で多対多の関係にデータを挿入するための回答を参照して、何をすべきか、どのように行うことができるかを理解してください。

于 2012-05-10T07:10:30.170 に答える