Flask实战第56天:板块管理
cms布局
编辑 cms_boards.html
{% block main_content %}
<div class="top-box">
<button class="btn btn-warning" data-toggle="modal" data-target="#banner-dialog">添加新板块</button>
</div> <table class="table table-bordered">
<thead>
<tr>
<th>板块名称</th>
<th>帖子数量</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
{% endblock %}
给 “添加轮播图“加上样式”
{% block head %}
<style>
.top-box button{
float: right;
} .top-box{
overflow: hidden;
background: #ecedf0;
padding: 10px;
}
</style>
{% endblock %}
添加新板块后端
首先添加个表, 因为板块前后端都要用到,编辑apps.models.py
class BoardModel(db.Model):
__tablename__ = 'board'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(20), nullable=False)
create_time = db.Column(db.DateTime, default=datetime.now)
同步表到数据库
>python manage.py db migrate
python manage.py db upgrade
添加个表单验证,编辑cms.forms.py
class AddBoardForm(BaseForm):
name = StringField(validators=[InputRequired(message='请输入板块名称')])
编辑cms.views.py
...
from apps.models import BoardModel
from .forms import AddBoardForm @bp.route('/aboard/', methods=['POST'])
@login_required
@permission_required(CMSPersmission.BOARDER)
def aboard():
add_form_board = AddBoardForm(request.form)
if add_form_board.validate():
name = add_form_board.name.data
board = BoardModel(name=name)
db.session.add(board)
db.session.commit()
return xjson.json_success(message='添加板块成功')
else:
return xjson.json_param_error(message=add_form_board.get_error())
添加板块的逻辑写好了,我们顺便把更新板块,删除板块一起写了
编辑cms.forms.py
class UpdateBoardForm(AddBoardForm):
board_id = IntegerField(validators=[InputRequired(message='请输入板块id')])
编辑cms.views.py
from .forms import UpdateBoardForm @bp.route('/uboard/', methods=['POST'])
@login_required
@permission_required(CMSPersmission.BOARDER)
def uboard():
update_board_form = UpdateBoardForm(request.form)
if update_board_form.validate():
board_id = update_board_form.board_id.data
name = update_board_form.name.data
if board_id:
board = BoardModel.query.get(board_id)
board.name = name
db.session.commit()
return xjson.json_success(message='更新成功')
else:
return xjson.json_param_error(message='板块不存在')
else:
return xjson.json_param_error(message=update_board_form.get_error()) @bp.route('/dboard/', methods=['POST'])
@login_required
@permission_required(CMSPersmission.BOARDER)
def dboard():
board_id = request.form.get('board_id')
if not board_id:
return xjson.json_param_error(message='请传入板块id')
board = BoardModel.query.get(board_id)
if not board:
return xjson.json_param_error(message='没有这个板块')
db.session.delete(board)
db.session.commit()
return xjson.json_success(message='删除板块成功')
传递板块数据到前端页面
@bp.route('/boards/')
@login_required
@permission_required(CMSPersmission.BOARDER)
def boards():
all_boards = BoardModel.query.all()
context = {
'boards': all_boards
}
return render_template('cms/cms_boards.html', **context)
cms 前端js
给“添加新板块"按钮加上 id
<button class="btn btn-warning" data-toggle="modal" data-target="#banner-dialog" id="add-board-btn">添加新板块</button>
创建static/cms/js/boards.js
$(function () {
$('#add-board-btn').click(function (event) {
event.preventDefault();
xtalert.alertOneInput({
'text': '请输入板块名称',
'placeholder': '板块名称',
'confirmCallback': function (inputValue) {
bbsajax.post({
'url': '/cms/aboard/',
'data': {
'name':inputValue
},
'success': function (data) {
if(data['code'] ==200){
window.location.reload();
}else{
xtalert.alertInfo(data['message'])
}
}
});
}
});
});
});
编辑cms_boards.html
引入boards.js
{% block head %}
<script src="{{ url_for('static', filename='cms/js/boards.js')}}"></script>
...
{% endblock %}
动态展示数据
<table class="table table-bordered">
<thead>
<tr>
<th>板块名称</th>
<th>帖子数量</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for board in boards %}
<tr>
<td>{{ board.name }}</td>
<td>暂未实现</td>
<td>{{ board.create_time }}</td>
<td>
<button class="btn btn-default btn-xs edit-board-btn">编辑</button>
<button class="btn btn-danger btn-xs delete-board-btn">删除</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
编辑板块
我们先把 板块名称和板块id 绑定到 tr上面,以方便js 获取
{% for board in boards %}
<tr data-id="{{ board.id }}" data-name="{{ board.name }}">
<td>{{ board.name }}</td>
<td>暂未实现</td>
<td>{{ board.create_time }}</td>
<td>
<button class="btn btn-default btn-xs edit-board-btn">编辑</button>
<button class="btn btn-danger btn-xs delete-board-btn">删除</button>
</td>
</tr>
{% endfor %}
编辑banners.js
$(function () {
$('.edit-board-btn').click(function () {
var self = $(this);
var tr = self.parent().parent();
var name = tr.attr('data-name');
var board_id = tr.attr('data-id'); xtalert.alertOneInput({
'text': '请输入新板块名称',
'placeholder': name,
'confirmCallback': function (inputValue) {
bbsajax.post({
'url': '/cms/uboard/',
'data': {
'board_id': board_id,
'name': inputValue
},
'success': function (data) {
if (data['code'] == 200) {
window.location.reload();
} else {
xtalert.alertInfo(data['message'])
}
}
});
}
});
})
});
删除板块
编辑banner.js
$(function () {
$('.delete-board-btn').click(function () {
var self = $(this);
var tr = self.parent().parent();
var board_id = tr.attr('data-id'); bbsajax.post({
'url': '/cms/dboard/',
'data': {
'board_id': board_id
},
'success': function (data) {
if (data['code'] == 200) {
window.location.reload();
} else {
xtalert.alertInfo(data['message'])
}
}
});
});
});
前台页面完成
视图函数传递板块信息,编辑front_views.py
@bp.route('/')
def index():
banners = BannerModel.query.order_by(BannerModel.priority.desc()).all()
boards = BoardModel.query.all()
context = {
'banners': banners,
'boards': boards
}
return render_template('front/front_index.html', **context)
编辑front_index.html
<div class="lg-container">
<div class="sm-container">
<div style="padding-bottom: 10px">
<button class="btn btn-warning btn-block">发布帖子</button>
</div> <div class="list-group">
<a href="#" class="list-group-item active">所有板块</a>
{% for board in boards %}
<a href="#" class="list-group-item ">{{ board.name }}</a>
{% endfor %}
</div>
</div>
Flask实战第56天:板块管理的更多相关文章
- Flask实战-留言板-安装虚拟环境、使用包组织代码
Flask实战 留言板 创建项目目录messageboard,从GreyLi的代码中把Pipfile和Pipfile.lock文件拷贝过来,这两个文件中定义了虚拟环境中需要安装的包的信息和位置,进入m ...
- Flask实战第37天:服务器权限验证
完成服务器权限验证之前,我们先如下页面先补上 帖子管理 {% extends 'cms/cms_base.html' %} {% block title %} 帖子管理-CMS管理系统 {% endb ...
- 36、Flask实战第36天:客户端权限验证
编辑cms_base.html <li><a href="#">{{ g.cms_user.username }}<span>[超级管理员]&l ...
- 13 | 实战:单机如何实现管理百万主机的心跳服务? https://time.geekbang.org/column/article/240656
13 | 实战:单机如何实现管理百万主机的心跳服务? https://time.geekbang.org/column/article/240656
- Flask实战第61天:帖子板块过滤显示
先在显示的帖子是所有版块的帖子,这节我们来完成点击某个版块,则显示此版块的帖子 要完成这个功能,我们需要在前端传递板块的id到后台, 编辑front_index.html 编辑首页视图 编辑板块选中样 ...
- Flask实战第49天:cms轮播图管理页面布局
新建cms_banners.html继承cms_base.html {% extends 'cms/cms_base.html' %} {% block title %} 轮播图管理-CMS管理系统 ...
- 1、Flask实战第1天:第一个Flask程序
Flask是流行的python web框架...(* ̄︶ ̄) 零基础到企业级论坛实战,人生苦短,我用python,开启FLask之旅吧... 安装开发环境 下载Python win版安装包 双击运行, ...
- Linux实战教学笔记14:用户管理初级(下)
第十四节 用户管理初级(下) 标签(空格分隔): Linux实战教学笔记-陈思齐 ---更多资料点我查看 1,用户查询相关命令id,finger,users,w,who,last,lastlog,gr ...
- Flask 源码流程,上下文管理
源码流程 创建对象 from flask import Flask """ 1 实例化对象 app """ app = Flask(__na ...
随机推荐
- [Luogu 2590] ZJOI2008 树的统计
[Luogu 2590] ZJOI2008 树的统计 裸树剖不解释. 比板子还简单. #include <algorithm> #include <cstdio> #inclu ...
- static变量与context泄漏
1.mContext--- public class LoginActivity extends BaseActivity { .... /**初始化信息*/ private vo ...
- 01-UIScrollView01-大图片展示
源代码下载链接:01-UIScrollView01-大图片展示.zip283.7 KB // // MJViewController.m // 01-UIScrollView01-大图 ...
- HDU 2577 How to Type (字符串处理)
题目链接 Problem Description Pirates have finished developing the typing software. He called Cathy to te ...
- device tree --- label
[label:] <device node name>[@ unit-address] 為 device node 取 label name, 可以在其它位置使用 &label 存 ...
- python 基础 习题
1.执行 Python 脚本的两种方式2.简述位.字节的关系 1Byte = 8bits 3.简述 ascii.unicode.utf-8.gbk 的关系 都是字符集,unicode兼容其他3种字符集 ...
- Elasticsearch( 插件开发)
elasticsearch5.2.2 插件开发(一) Scripting plugins:这个插件本质来说,就是会调用用户的脚本,所以可以执行任何的程序,举例的话,可以通过这个插件,支持javascr ...
- 《java并发编程实战》读书笔记11--构建自定义的同步工具,条件队列,Condition,AQS
第14章 构建自定义的同步工具 本章将介绍实现状态依赖性的各种选择,以及在使用平台提供的状态依赖机制时需要遵守的各项规则. 14.1 状态依赖性的管理 对于并发对象上依赖状态的方法,虽然有时候在前提条 ...
- Asp.net 模板下载和导入到DataTable中
HTML页面: <tr> <td colspan=" style="text-align: left; border: 1px;"> <as ...
- redis之(十二)redis数据的持久化
[一]redis的数据为什么要持久化 --->redis的存取数据性能高,是由于将所有数据都存储在内存中.当redis重启的时候,存储在内存中的数据就容易丢失. --->把redis作为数 ...