帖子序列化
继承SerializerMixin 即可调用to_dict()序列化
后端
class PostModel(db.Model, SerializerMixin):
serialize_only = ("id", "title", "content", "create_time", "board", "author")
__tablename__ = "post"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(200), nullable=False)
content = db.Column(db.Text, nullable=False)
create_time = db.Column(db.DateTime, default=datetime.now)
board_id = db.Column(db.Integer, db.ForeignKey("board.id"))
author_id = db.Column(db.String(100), db.ForeignKey("user.id"))
# 这里关联了BoardModel 也会将其序列化 所以 BoardModel也需要继承SerializerMixin
# 另外 序列化的时候会给BoardModel添加一个属性posts
board = db.relationship("BoardModel", backref=db.backref("posts"))
author = db.relationship("UserModel", backref=db.backref("posts"))
这里会出现一个循环序列化的问题
解决办法就是给BoardModel指定序列化字段
class BoardModel(db.Model, SerializerMixin):
serialize_only = ("id", "name", "priority", "create_time")
__tablename__ = "board"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(20), unique=True)
priority = db.Column(db.Integer, default=1)
create_time = db.Column(db.DateTime, default=datetime.now)
#相当于这样 会循环序列化
# posts = BoardModel
class PostModel(db.Model, SerializerMixin):
serialize_only = ("id", "title", "content", "create_time", "board", "author")
__tablename__ = "post"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(200), nullable=False)
content = db.Column(db.Text, nullable=False)
create_time = db.Column(db.DateTime, default=datetime.now)
board_id = db.Column(db.Integer, db.ForeignKey("board.id"))
author_id = db.Column(db.String(100), db.ForeignKey("user.id"))
# 这里关联了BoardModel 也会将其序列化 所以 BoardModel也需要继承SerializerMixin
# 另外 序列化的时候会给BoardModel添加一个属性posts
board = db.relationship("BoardModel", backref=db.backref("posts"))
author = db.relationship("UserModel", backref=db.backref("posts"))
@bp.get("/post/list")
def post_list():
page = request.args.get('page', default=1, type=int)
per_page_count = current_app.config['PER_PAGE_COUNT']
start = (page-1)*per_page_count
end = start + per_page_count
query_obj = PostModel.query.order_by(PostModel.create_time.desc())
total_count = query_obj.count()
posts = query_obj.slice(start, end)
# [PostModel(1),PostModel(2)]
post_list = [post.to_dict() for post in posts]
return restful.ok(data={
'total_count': total_count,
"post_list": post_list,
"page": page
})
前端
getPostList(page){
const url = "/post/list?page=" + (page?page:1)
return this.http.get(url);
}
// 响应拦截 每次都要获取data之外的数据,可以在这里拦截直接获取data
this.http.interceptors.response.use(response => {
return response.data;
})
return {
deletingIndex: 0,
confirmDialogVisible: false,
posts: [],
total_count: 0,
page: 1
};
getPostList(page){
this.$http.getPostList(page).then(result => {
if(result['code'] == 200){
let data = result['data'];
this.posts = data['post_list'];
this.total_count = data['total_count'];
this.page = data['page'];
}
})
},
deletePost(post_id){
const url = "/post/delete"
return this._post(url, {"id": post_id})
<template>
<div>
<el-space direction="vertical" :size="20">
<h1>帖子管理</h1>
<el-table :data="posts" style="width: 100%">
<el-table-column label="标题">
<template #default="scope">
<a :href="$http.server_host + '/post/detail/' + scope.row.id" target="_blank">{{
scope.row.title
}}</a>
</template>
</el-table-column>
<el-table-column prop="create_time" label="发布时间" width="180" />
<el-table-column prop="board.name" label="所属板块" />
<el-table-column prop="author.username" label="作者" />
<el-table-column label="操作">
<template #default="scope">
<el-button
type="danger"
circle
size="mini"
@click="onDeletePostClick(scope.$index)"
>
<el-icon><delete /></el-icon>
</el-button>
</template>
</el-table-column>
</el-table>
<div style="text-align: center;">
<el-pagination
background
layout="prev, pager, next"
:total="total_count"
:current-page="page"
@current-change="onPageChanged"
>
</el-pagination>
</div>
</el-space>
<!-- 删除轮播图确认对话框 -->
<el-dialog
v-model="confirmDialogVisible"
title="提示"
width="30%"
>
<span>如果删除帖子,该帖子下所有的评论也会被删除,您确定要删除吗?</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="confirmDialogVisible = false">取消</el-button>
<el-button type="primary" @click="onConfirmDeletePostClick">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
import {Delete} from "@element-plus/icons";
import { ElMessage } from 'element-plus';
export default {
name: "Post",
data() {
return {
deletingIndex: 0,
confirmDialogVisible: false,
posts: [],
total_count: 0,
page: 1
};
},
mounted() {
this.getPostList(1);
},
methods: {
getPostList(page){
this.$http.getPostList(page).then(result => {
if(result['code'] == 200){
let data = result['data'];
this.posts = data['post_list'];
this.total_count = data['total_count'];
this.page = data['page'];
}
})
},
onDeletePostClick(index) {
this.confirmDialogVisible = true;
this.deletingIndex = index;
},
onConfirmDeletePostClick(){
let post = this.posts[this.deletingIndex];
this.$http.deletePost(post.id).then(res => {
if(res['code'] == 200){
this.posts.splice(this.deletingIndex, 1);
ElMessage.success("帖子删除成功!");
this.confirmDialogVisible = false;
}else{
ElMessage.info(res['message']);
}
})
},
onPageChanged(current_page){
this.getPostList(current_page);
}
},
components: {
Delete
}
};
</script>
<style scoped>
.el-space {
display: block;
}
</style>
删除后端
@bp.post("/post/delete")
@permission_required(Permission.POST)
def delete_post():
post_id = request.form.get("id")
try:
post_model = PostModel.query.get(post_id)
except Exception as e:
return restful.params_error(message="帖子不存在!")
db.session.delete(post_model)
db.session.commit()
return restful.ok()