如何在Starlette-Admin中显示主题关联的帖子与评论
解决方案
步骤1:完善ORM模型的反向关联
首先需要在Theme类中添加与Post、Comment的反向关联关系,这样才能在主题详情页获取到关联的帖子和评论数据。修改orm.py:
from sqlalchemy.orm import relationship from models.tables import Base, theme_table, post_table, comment_table class Theme(Base): __table__ = theme_table # 添加反向关联,与Post、Comment的theme字段对应 posts = relationship("Post", back_populates="theme") comments = relationship("Comment", back_populates="theme") class Post(Base): __table__ = post_table # 补充back_populates关联到Theme的posts字段 theme = relationship(Theme, back_populates="posts") class Comment(Base): __table__ = comment_table # 补充back_populates关联到Theme的comments字段 theme = relationship(Theme, back_populates="comments")
步骤2:修改Admin配置,添加关联数据表格
在admin_panel.py中,修改ThemeAdmin类,通过自定义模板字段在详情页渲染关联的帖子和评论表格,同时保留Starlette-Admin的原生样式。另外需要完成视图注册和挂载:
from sqlalchemy import create_engine from starlette_admin.contrib.sqla import Admin, ModelView from starlette_admin import TemplateField from models.orm import Theme, Comment, Post def init_admin(app): engine = create_engine("sqlite:///test.db", connect_args={"check_same_thread": False}) admin = Admin( engine, base_url='/test/admin', title='Test Admin' ) class ThemeAdmin(ModelView): name = 'Theme' label = 'Themes' # 配置详情页字段:先显示主题自身字段,再添加关联数据表格 detail_fields = [ # 替换成你的Theme表实际字段,比如id、name等 "id", "name", # 渲染关联帖子表格 TemplateField( name="关联帖子", template_path="admin/related_posts.html" ), # 渲染关联评论表格 TemplateField( name="关联评论", template_path="admin/related_comments.html" ) ] class PostAdmin(ModelView): name = 'Post' label = 'Posts' class CommentAdmin(ModelView): name = 'Comment' label = 'Comments' # 注册所有视图 admin.add_view(ThemeAdmin(Theme)) admin.add_view(PostAdmin(Post)) admin.add_view(CommentAdmin(Comment)) # 将admin挂载到app admin.mount_to(app)
步骤3:创建关联数据模板文件
在项目的templates/admin目录下创建两个模板文件,使用Starlette-Admin原生的Bootstrap样式渲染表格,同时为每条数据添加详情链接。
templates/admin/related_posts.html
{% if obj.posts %} <div class="card mt-3"> <div class="card-header"> <h5>{{ field.name }}</h5> </div> <div class="card-body p-0"> <table class="table table-striped mb-0"> <thead> <tr> <th>ID</th> <th>标题</th> <!-- 替换成你的Post表实际字段,比如title --> <th>操作</th> </tr> </thead> <tbody> {% for post in obj.posts %} <tr> <td>{{ post.id }}</td> <td>{{ post.title }}</td> <td> <a href="{{ url_for('admin:detail', identity=post.__class__.__name__, pk=post.id) }}" class="btn btn-sm btn-primary">查看详情</a> </td> </tr> {% endfor %} </tbody> </table> </div> </div> {% else %} <p class="text-muted mt-3">暂无关联帖子</p> {% endif %}
templates/admin/related_comments.html
{% if obj.comments %} <div class="card mt-3"> <div class="card-header"> <h5>{{ field.name }}</h5> </div> <div class="card-body p-0"> <table class="table table-striped mb-0"> <thead> <tr> <th>ID</th> <th>内容</th> <!-- 替换成你的Comment表实际字段,比如content --> <th>操作</th> </tr> </thead> <tbody> {% for comment in obj.comments %} <tr> <td>{{ comment.id }}</td> <td>{{ comment.content }}</td> <td> <a href="{{ url_for('admin:detail', identity=comment.__class__.__name__, pk=comment.id) }}" class="btn btn-sm btn-primary">查看详情</a> </td> </tr> {% endfor %} </tbody> </table> </div> </div> {% else %} <p class="text-muted mt-3">暂无关联评论</p> {% endif %}
说明
- 模板中的字段(比如
title、content)需要替换成你数据库表中实际的字段名 - 模板使用了Starlette-Admin默认的Bootstrap样式类(
card、table table-striped),确保和原生界面风格一致 - 每条关联数据的详情链接通过
url_for生成,自动跳转到对应模型的详情页
内容的提问来源于stack exchange,提问作者Bimbo
相关产品推荐
相关产品推荐

