DevGang
Авторизоваться

SQLAlchemy и Flask-Admin: теги для записей со связь Many to Many

Для нашего блога решил добавить теги, чтобы похожие записи было проще искать и вообще это модно сейчас. Ранее использовал обычный массив с ForeignKey, и это работает, но... Всегда есть но, в Flask-Admin для того чтобы появился мультиселект с вариантами из другой таблички этого уже недостаточно.

И так начнем с проблемы: 

Есть много тегов и также немало статей, их нужно связать методом "многий ко многим", а для удобства редактирование в админ панели, в форме редактирования статьи, должен появится мультиселект с этими самыми тегами.

Начнем с модельки самого тега, тут есть одна особенность:

class TagModel(db.Model):

    __tablename__ = 'tag'

    id = db.Column(db.Integer, primary_key=True)

    name = db.Column(db.String)
    weight = db.Column(db.Integer, index=True, default=0)

    create_date = db.Column(db.DateTime, default=datetime.datetime.now)

    def __str__(self):
        return self.name

Для того что-бы Flask-Admin в селекте выводил нормально название добавляем функцию __str__, она то как раз и будет отвечать за формирование имени в селекте.

Далее модель статьи:

class ArticleModel(db.Model):

    __tablename__ = 'article'

    _cover = None

    id = db.Column(db.Integer, primary_key=True)

    chpu = db.Column(db.String)
    title = db.Column(db.String)
    keywords = db.Column(db.String)
    description = db.Column(db.String)

    state = db.Column(db.Integer, index=True, default=ARTICLE_EDIT)

    tags = db.relationship(TagModel, secondary=article_tags_meta)

    cover_id = db.Column(db.Integer)
    name = db.Column(db.String)
    preview = db.Column(db.String)
    body = db.Column(db.TEXT)

    update_date = db.Column(db.DateTime, default=datetime.datetime.now)
    create_date = db.Column(db.DateTime, default=datetime.datetime.now)

Здесь мы добавиляем отношение:

tags = db.relationship(TagModel, secondary=article_tags_meta)

article_tags_meta это промежуточная таблица со связями, выглядет она следующим образом:

article_tags_meta = db.Table(
    'article_tags',
    db.Model.metadata,
    db.Column('article_id', db.Integer, db.ForeignKey('article.id')),
    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
    extend_existing=True
)

И по результату, без лишней магии и телодвижений получаем в админ панели:

#Flask
Комментарии 1
Pavel Braha 06.08.2021 в 02:23

Для того что-бы Flask-Admin в селекте выводил нормально название добавляем функцию str, она то как раз и будет отвечать за формирование имени в селекте... ты мне жизнь спас)

Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу