python操作mysql④python服务端flask和前端bootstrap框架结合实现新闻展示
参考文档
http://flask.pocoo.org/docs/0.11/
http://flask-sqlalchemy.pocoo.org/2.1/
中文版
http://docs.jinkan.org/docs/flask/
涉及分页部分知识,请参考:
http://www.cnblogs.com/reblue520/p/8483557.html
安装flask和Flask-SQLAlchemy
C:Usersajie>pip install flask
C:Usersajie>pip install Flask-SQLAlchemy
数据表和数据 CREATE TABLE `news` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(200) NOT NULL, `content` varchar(2000) NOT NULL, `types` varchar(10) NOT NULL, `image` varchar(300) DEFAULT NULL, `author` varchar(20) DEFAULT NULL, `view_count` int(11) DEFAULT '0', `created_at` datetime DEFAULT NULL, `is_valid` smallint(6) DEFAULT '1', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8; INSERT INTO `news` VALUES ('1', '朝鲜特种部队视频公布 展示士兵身体素质与意志', '新闻内容', '推荐', '/static/img/news/01.jpg', null, '0', '2018-02-28 20:34:20', '1'); INSERT INTO `news` VALUES ('2', '男子长得像"祁同伟"挨打 打人者:为何加害检察官', '新闻内容', '百家', '/static/img/news/02.jpg', null, '0', '2018-03-01 20:34:29', '1'); INSERT INTO `news` VALUES ('3', '导弹来袭怎么办?日本政府呼吁国民堕入地下通道', '新闻内容', '本地', '/static/img/news/03.png', null, '0', null, '1'); INSERT INTO `news` VALUES ('4', '美监:朝在建能发射3发以上导弹的3000吨级新潜艇', '新闻内容', '推荐', '/static/img/news/04.png', null, '0', null, '1'); INSERT INTO `news` VALUES ('5', '证监会:前发审委员冯小树违法买卖股票被罚4.99亿', '新闻内容', '百家', '/static/img/news/08.png', null, '0', null, '1'); INSERT INTO `news` VALUES ('6', '外交部回应安倍参拜靖国神社:同军国主义划清界限', '新闻内容', '推荐', '/static/img/news/new1.jpg', null, '0', null, '1'); INSERT INTO `news` VALUES ('7', '"萨德"供地违法?韩民众联名起诉要求撤回供地', '新闻内容', '百家', '/static/img/news/new2.jpg', null, '0', null, '1'); INSERT INTO `news` VALUES ('10', '标题1', '新闻内容1', '推荐', '/static/img/news/01.png', null, '0', null, '1'); INSERT INTO `news` VALUES ('11', '标题20180202', '内容20180202', '百家', null, null, null, null, null); INSERT INTO `news` VALUES ('12', '标题0', '内容0', '百家0', null, null, null, null, null); INSERT INTO `news` VALUES ('13', '标题1', '内容1', '百家1', null, null, null, null, null); INSERT INTO `news` VALUES ('14', '标题2', '内容2', '百家2', null, null, null, null, null); INSERT INTO `news` VALUES ('15', '标题3', '内容3', '百家3', null, null, null, null, null); INSERT INTO `news` VALUES ('16', '标题4', '内容4', '百家4', null, null, null, null, null); INSERT INTO `news` VALUES ('17', '标题5', '内容5', '百家5', null, null, null, null, null); INSERT INTO `news` VALUES ('18', '标题6', '内容6', '百家6', null, null, null, null, null); INSERT INTO `news` VALUES ('19', '标题7', '内容7', '百家7', null, null, null, null, null); INSERT INTO `news` VALUES ('20', '标题8', '内容8', '百家8', null, null, null, null, null); INSERT INTO `news` VALUES ('21', '标题9', '内容9', '百家9', null, null, null, null, null); INSERT INTO `news` VALUES ('22', '标题0', '内容0', '百家0', null, null, null, null, null); INSERT INTO `news` VALUES ('23', '标题1', '内容1', '百家1', null, null, null, null, null); INSERT INTO `news` VALUES ('24', '标题2', '内容2', '百家2', null, null, null, null, null); INSERT INTO `news` VALUES ('25', '标题3', '内容3', '百家3', null, null, null, null, null); INSERT INTO `news` VALUES ('26', '标题4', '内容4', '百家4', null, null, null, null, null); INSERT INTO `news` VALUES ('27', '标题5', '内容5', '百家5', null, null, null, null, null); INSERT INTO `news` VALUES ('28', '标题6', '内容6', '百家6', null, null, null, null, null); INSERT INTO `news` VALUES ('29', '标题7', '内容7', '百家7', null, null, null, null, null); INSERT INTO `news` VALUES ('30', '标题8', '内容8', '百家8', null, null, null, null, null); INSERT INTO `news` VALUES ('31', '标题9', '内容9', '百家9', null, null, null, null, null); INSERT INTO `news` VALUES ('32', '标题0', '内容0', '百家0', null, null, null, null, null); INSERT INTO `news` VALUES ('33', '标题1', '内容1', '百家1', null, null, null, null, null); INSERT INTO `news` VALUES ('34', '标题2', '内容2', '百家2', null, null, null, null, null); INSERT INTO `news` VALUES ('35', '标题3', '内容3', '百家3', null, null, null, null, null); INSERT INTO `news` VALUES ('36', '标题4', '内容4', '百家4', null, null, null, null, null); INSERT INTO `news` VALUES ('37', '标题5', '内容5', '百家5', null, null, null, null, null); INSERT INTO `news` VALUES ('38', '标题6', '内容6', '百家6', null, null, null, null, null); INSERT INTO `news` VALUES ('39', '标题7', '内容7', '百家7', null, null, null, null, null); INSERT INTO `news` VALUES ('40', '标题8', '内容8', '百家8', null, null, null, null, null); INSERT INTO `news` VALUES ('41', '标题9', '内容9', '百家9', null, null, null, null, null); INSERT INTO `news` VALUES ('42', '标题0', '内容0', '百家0', null, null, null, null, null); INSERT INTO `news` VALUES ('43', '标题1', '内容1', '百家1', null, null, null, null, null); INSERT INTO `news` VALUES ('44', '标题2', '内容2', '百家2', null, null, null, null, null); INSERT INTO `news` VALUES ('45', '标题3', '内容3', '百家3', null, null, null, null, null); INSERT INTO `news` VALUES ('46', '标题4', '内容4', '百家4', null, null, null, null, '1'); INSERT INTO `news` VALUES ('47', '标题5', '内容5', '百家5', null, null, null, null, '1'); INSERT INTO `news` VALUES ('48', '标题6', '内容6', '百家6', null, null, null, null, '1'); INSERT INTO `news` VALUES ('49', '标题7', '内容7', '百家7', null, null, null, null, '1'); INSERT INTO `news` VALUES ('50', '标题8', '内容8', '百家8', null, null, null, null, '1');
1.flask一个小的测试程序
#coding:utf-8 from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'hello flask' if __name__ == "__main__": app.run(debug = True)
启动程序
D:pythonpython_db>python python_mysql_orm02_flask01.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger pin code: 127-366-472
127.0.0.1 - - [05/Feb/2018 19:40:36] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [05/Feb/2018 19:40:36] "GET /favicon.ico HTTP/1.1" 404 -
2.简单的模板渲染处理
from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask import render_template app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:@localhost:3306/news_test?charset=utf8' db = SQLAlchemy(app) class News(db.Model): __tablename__ = 'news' id = db.Column(db.Integer, primary_key = True) title = db.Column(db.String(200), nullable = False) content = db.Column(db.String(2000), nullable = False) types = db.Column(db.String(10), nullable = False) image = db.Column(db.String(1300), ) author = db.Column(db.String(20), ) view_count = db.Column(db.Integer) created_at = db.Column(db.DateTime) is_valid = db.Column(db.Boolean) @app.route('/hello') def hello_world(): return 'hello flask' ''' 创建news_test数据库 建表 cmd下输入Python,导入包,使用命令生成表,并进行简单的操作 >>> from flask_news import db >>> from flask_news import News >>> news01 = News(title= 'title01',content='content01',types='baijia') >>> db.session.add(news01) >>> db.session.commit() ''' @app.route('/') def index(): '''新闻首页''' return render_template('index.html') @app.route('/cat/<name>/') def cat(name): '''新闻的类别''' # 查询 return render_template('cat.html', name = name) @app.route('/detail/<int:pk>/') def detail(pk): '''新闻详情信息''' return render_template('detail.html', pk = pk) if __name__ == "__main__": app.run(debug = True)
3.示例:新闻相关的页面程序
目录结构 ├── flask_news.py ├── static │ ├── bootstrap-3.3.7-dist │ │ ├── css │ │ ├── fonts │ │ └── js │ ├── bootstrap-3.3.7-dist.zip │ ├── datatables.min.css │ ├── datatables.min.js │ ├── img │ │ └── news │ ├── index.css │ ├── jquery-3.3.1.min.js │ └── main.css └── templates ├── cat.html ├── detail.html └── index.html
①服务端程序flask_news.py
from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask import render_template, redirect app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:@localhost:3306/news?charset=utf8' db = SQLAlchemy(app) class News(db.Model): __tablename__ = 'news' id = db.Column(db.Integer, primary_key = True) title = db.Column(db.String(200), nullable = False) content = db.Column(db.String(2000), nullable = False) types = db.Column(db.String(10), nullable = False) image = db.Column(db.String(1300), ) author = db.Column(db.String(20), ) view_count = db.Column(db.Integer) created_at = db.Column(db.DateTime) is_valid = db.Column(db.Boolean) @app.route('/hello') def hello_world(): return 'hello flask' ''' 创建news_test数据库 建表 cmd下输入Python,导入包,使用命令生成表,并进行简单的操作 >>> from flask_news import db >>> from flask_news import News >>> news01 = News(title= 'title01',content='content01',types='baijia') >>> db.session.add(news01) >>> db.session.commit() ''' @app.route('/') def index(): '''新闻首页''' news_list = News.query.all() print(news_list) return render_template('index.html', news_list = news_list) @app.route('/index/') def index_html(): '''新闻首页''' new_list = News.query.all() return redirect('/') @app.route('/cat/<name>/') def cat(name): '''新闻的类别''' # 查询 news_list = News.query.filter(News.types == name) return render_template('cat.html', name = name, news_list = news_list) @app.route('/detail/<int:pk>/') def detail(pk): '''新闻详情信息''' obj = News.query.get(pk) return render_template('detail.html', obj = obj) if __name__ == "__main__": app.run(debug = True)
②templates模板页面
a.首页index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</title> <link rel="stylesheet" href="{{ url_for('static', filename='bootstrap-3.3.7-dist/css/bootstrap.min.css')}}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='main.css')}}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='datatables.min.css')}}"> <script type="text/javascript" src="{{ url_for('static', filename='jquery-3.3.1.min.js')}}"></script> <script type="text/javascript"> $(document).ready(function() { $('#example').DataTable(); } ); </script> </head> <body> <div class="container"> <h1>新闻列表</h1> <nav class="navbar navbar-inverse"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-menu" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <!-- <a class="navbar-brand" href="#">首页</a> --> </div> <div id="navbar-menu" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li class="active"><a href="index">首页</a></li> <li><a href="{{url_for('cat', name='推荐')}}">推荐</a></li> <li><a href="{{url_for('cat', name='百家')}}">百家</a></li> <li><a href="{{url_for('cat', name='推荐')}}">本地</a></li> <li><a href="{{url_for('cat', name='图片')}}">图片</a></li> </ul> </div> </nav> <div id="content" class="row-fluid"> <div class="col-md-12"> <table id="example" class="table table-striped table-bordered" cellspacing="0" width="100%"> <thead> <tr> <th>图片</th> <th>简介</th> </tr> </thead> <tfoot> <tr> <th>Name</th> <th>Position</th> </tr> </tfoot> <!-- {% for obj in news_list %} <div class="col-md-9"> <div class="img-content"> <img src="{{ obj.image }}" alt="图片"> </div> <div class="right-content"> <p> <a href="{{ url_for('detail', pk=obj.id) }}">{{ obj.title }}</a> <small>{{ obj.created_at }}</small> </p> </div> </div> {% endfor %} --> <tbody> {% for obj in news_list %} <tr> <td> <img width=120 height=60 src="{{ obj.image }}" alt="图片"> </td> <td> <p> <a href="{{ url_for('detail', pk=obj.id) }}">{{ obj.title }}</a> <small>{{ obj.created_at }}</small> </p> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> <script type="text/javascript" src="{{ url_for('static', filename = 'datatables.min.js')}}"></script> </body> </html>
b.详情页detail.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>新闻详情</title> <link rel="stylesheet" href="{{ url_for('static', filename='bootstrap-3.3.7-dist/css/bootstrap.min.css')}}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='main.css')}}"> </head> <body> <div class="container"> <h1>新闻列表</h1> <nav class="navbar navbar-inverse"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-menu" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <!-- <a class="navbar-brand" href="#">首页</a> --> </div> <div id="navbar-menu" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li class="active"><a href="index">首页</a></li> <li><a href="{{url_for('cat', name='推荐')}}">推荐</a></li> <li><a href="{{url_for('cat', name='百家')}}">百家</a></li> <li><a href="{{url_for('cat', name='推荐')}}">本地</a></li> <li><a href="{{url_for('cat', name='图片')}}">图片</a></li> </ul> </div> </nav> <div id="content" class="row-fluid"> <div class="col-md-9"> <h2>新闻详情,来自新闻id> {{obj.id}}</h2> </div> <div class="col-md-12"> <table id="example" class="table table-striped table-bordered" cellspacing="0" width="100%"> <thead> <tr> <th>具体新闻内容</th> </tr> </thead> <tbody> <tr> <td> <img width=600 height=500 src="{{ obj.image }}" alt="图片"> </td> <td> </tr> <tr> <td> <p> {{ obj.title }} <small>{{ obj.created_at }}</small> </p> </td> </tr> </tbody> </table> </div> </div> </div> </body> </html>
c.新闻类别cat.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>新闻类别</title> </head> <body> 新闻类别> {{name}} </body> </html>
static/main.css程序
.container {
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
@media (min- 768px) {
.container {
750px;
}
}
@media (min- 992px) {
.container {
970px;
}
}
@media (min- 1200px) {
.container {
1170px;
}
}
.container-fluid {
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
效果展示