python操作mysql⑥新闻管理后台功能的完善(增、删、改、查)
安装表单验证
D:\python\python_mysql_redis_mongodb\version02>pip install Flask-WTF

表单验证功能
http://flask.pocoo.org/docs/0.11/patterns/wtforms/

目录结构:

[root@node1 mysql_version03]# tree -L
.
├── flask_news.py
├── forms.py
├── static
│   ├── bootstrap-3.3.-dist
│   │   ├── css
│   │   ├── fonts
│   │   └── js
│   ├── bootstrap-3.3.-dist.zip
│   ├── datatables.min.css
│   ├── datatables.min.js
│   ├── img
│   │   └── news
│   ├── index.css
│   ├── jquery-3.3..min.js
│   └── main.css
└── templates
├── admin
│   ├── add.html
│   ├── admin_base.html
│   ├── index.html
│   └── update.html
├── cat.html
├── detail.html
├── home_base.html
└── index.html

1.服务端功能代码flask_news.py

# coding:utf-8
from flask import Flask, flash
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
from flask import render_template, redirect
from forms import NewsForm app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:@localhost:3306/news?charset=utf8' app.config['SECRET_KEY'] = 'adfa@4314#31AD23#2'
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) @app.route('/admin/')
@app.route('/admin/<int:page>/')
def admin(page=None):
'''后台新闻列表'''
if page is None:
page = 1
news_list = News.query.filter_by(is_valid=True).paginate(page = page, per_page = 3)
# print (news_list.items)
return render_template('admin/index.html', news_list = news_list) @app.route('/admin/update/<int:pk>/', methods = ['GET', 'POST'])
def admin_update(pk):
'''后台新闻列表'''
new_obj = News.query.get(pk)
print('admin_update:new_obj %s' % new_obj)
if not new_obj:
return redirect(url_for('admin')) form = NewsForm(obj = new_obj)
if form.validate_on_submit():
new_obj.title = form.title.data
new_obj.content = form.content.data
new_obj.types = form.types.data
new_obj.created_at = datetime.now()
# 保存数据
db.session.add(new_obj)
db.session.commit() # 文字提示flash消息闪现
flash('修改成功')
return redirect('/admin/') return render_template('admin/update.html', new_obj = new_obj,form = form) @app.route('/admin/add/')
def admin_add():
'''跳转到后台新闻列表'''
# 将form对象传入add.html页面
# 参考 http://flask-wtf.readthedocs.io/en/latest/quickstart.html#creating-forms
form = NewsForm()
return render_template('admin/add.html',form = form) @app.route('/admin/do_add/', methods = ['POST'])
def admin_do_add():
''' 新增新闻信息 '''
form = NewsForm()
if form.validate_on_submit():
# 获取数据
new_obj = News(
title = form.title.data,
content = form.content.data,
types = form.types.data,
image = form.image.data,
created_at = datetime.now()
)
# 保存数据
print(new_obj)
db.session.add(new_obj)
db.session.commit() # 文字提示flash消息闪现
flash('添加成功') return redirect('/admin/') @app.route('/admin/delete/<int:pk>/', methods = ['GET','POST'])
def admin_delete(pk):
''' 删除新闻信息 '''
new_obj = News.query.get(pk) if not new_obj:
return 'no' new_obj.is_valid = 0
db.session.add(new_obj)
db.session.commit() return 'yes' if __name__ == "__main__":
app.run(debug = True)

2.表单功能forms.py

from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, SubmitField, SelectField
from wtforms.validators import DataRequired class NewsForm(FlaskForm):
"""新闻表单数据验证"""
title = StringField(label = '新闻标题', validators = [DataRequired('请输入标题')],
description = '请输入标题',
render_kw={'required':'required', 'class':'form-control'})
content = TextAreaField(label = '新闻内容', validators = [DataRequired('请输入新闻内容')],
description = '请输入新闻内容',
render_kw={'required':'required', 'class':'form-control'})
types = SelectField('新闻类型', choices = [('推荐','推荐'), ('百家', '百家'),('本地','本地'), ('图片','图片')])
image = StringField(label='新闻图片', description='请输入图片地址',
render_kw={'required':'required', 'class':'form-control'})
submit = SubmitField('提交')

3.后台模板代码
①模板代码admin_base.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='bootstrap-3.3.7-dist/css/bootstrap.min.css')}}">
{% block head %}
<title>首页</title>
{% endblock %}
</head>
<body>
<!-- 导航栏 -->
<div class="container">
<div class="row">
<div class="bs-example" data-example-id="default-navbar">
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- 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="#bs-example-navbar-collapse-1" 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="{{ url_for('admin_add')}}">添加新闻</a>
</div> <!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav> <!-- 新闻内容部分 -->
{% block content %}
<!-- 内容区域 -->
{% endblock %}
</div>
{% block extrajs %}
<!-- 其他脚本 -->
{% endblock %}
</body>
</html>

②首页index.html

{% extends 'admin/admin_base.html' %}
{% block head %}
<title>新闻后台首页</title>
{% endblock %}
{% block content %}
<!-- 消息闪现 -->
{% for msg in get_flashed_messages() %}
<p class="bg-success">{{msg}}</p>
{% endfor %} <!-- 表格,存放新闻具体内容 -->
<table class="table table-hover"> <tr class="info">
<th>编号</th>
<th>新闻标题</th>
<th>类别</th>
<th>添加时间</th>
<th>操作</th>
</tr>
{% for new_obj in news_list.items %}
<tr class="active">
<td>{{ new_obj.id }}</td>
<td>{{ new_obj.title }}</td>
<td>{{new_obj.types }}</td>
<td>{{new_obj.created_at }}</td>
<td><a href='/admin/update/{{ new_obj.id }}/' class='btn btn-success'>修改</a><a data-url='{{ url_for('admin_delete', pk=new_obj.id) }}' href="javascript:;" class='btn btn-danger'>删除</a></td>
</tr>
{% endfor %}
</table> <!-- 分页,默认分页 --> <nav aria-label="Page navigation"> <ul class="pagination">
<!-- {% macro pagination_news_list(news_list, adaamin) %} -->
<li> {% if news_list.has_prev %}
<a href="#" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
{% else %}
{% endif %}
</li> {% for page in news_list.iter_pages() %}
<li>
<a href="{{ url_for('admin', page=page) }}">{{ page }}</a>
</li>
{% endfor %} <li>
{% if news_list.has_next %}
<a href="#" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
{% endif %}
</li> </ul>
<!-- {% endmacro %} -->
</nav> </div>
</div>
{% endblock %}
{% block extrajs %}
<script type="text/javascript">
// 通过ajax异步删除新闻
$(function(){
$('.btn-danger').on('click', function(){
var _this = $(this);
var url = _this.attr('data-url');
// 确认是否删除
if(confirm('确认删除吗?')){
// ajax调用
$.post(url, function(res){
//处理结果
if(res == 'yes'){
_this.parents('tr').hide()
}else{
alert('删除失败')
}
})
} })
})
</script>
{% endblock %}
</body>
</html>

③添加新闻add.html

{% extends 'admin/admin_base.html' %}
{% block head %}
<title>新闻添加页面</title>
{% endblock %}
{% block content %} <!-- 添加新闻内容 -->
<form action="/admin/do_add/" method="post">
<div class="form-group">
<label for="exampleInputEmail1">{{ form.title.label.text }}</label>
<input type="text" name="title" class="form-control" id="exampleInputEmail1" placeholder="news title">
</div>
<div class="form-group">
<label for="exampleInputPassword1">{{ form.types.label.text }}</label>
<div>
{{ form.types }}
</div>
</div>
<div class="form-group">
<label for="exampleInputFile">{{ form.image.label.text }}</label>
<input type="file" name="image" id="exampleInputFile">
<p class="help-block">新闻图片上传</p>
</div>
<div class="form-group">
{{ form.content }}
</div> <br>
{{ form.csrf_token }}
{{ form.submit }}
</form>
{% endblock %}
</body>
</html>

④修改新闻update.html

{% extends 'admin/admin_base.html' %}
{% block head %}
<title>修改新闻</title>
{% endblock %}
{% block content %} <form role='form' class="form-horizontal" method="post">
<div class="form-group">
<label for="exampleInputEmail1">{{ form.title.label.text }}</label>
<div>
{{form.title}}
</div>
</div>
<div class="form-group">
<label for="exampleInputPassword1">{{ form.types.label.text }}</label>
<div>
{{ form.types }}
</div>
</div>
<div class="form-group">
<label for="exampleInputFile">{{ form.image.label.text }}</label>
<input type="file" name="image" id="exampleInputFile">
<!-- <p class="help-block">新闻图片上传</p> -->
</div>
<div class="form-group">
{{ form.content }}
</div> <br>
{{ form.csrf_token }}
{{ form.submit }} </form>
{% endblock %}
</body>
</html>

python操作三大主流数据库(6)python操作mysql⑥新闻管理后台功能的完善(增、ajax异步删除新闻、改、查)的更多相关文章

  1. python操作三大主流数据库(14)python操作redis之新闻项目实战②新闻数据的展示及修改、删除操作

    python操作三大主流数据库(14)python操作redis之新闻项目实战②新闻数据的展示及修改.删除操作 项目目录: ├── flask_redis_news.py ├── forms.py ├ ...

  2. python操作三大主流数据库(12)python操作redis的api框架redis-py简单使用

    python操作三大主流数据库(12)python操作redis的api框架redis-py简单使用 redispy安装安装及简单使用:https://github.com/andymccurdy/r ...

  3. python操作三大主流数据库(10)python操作mongodb数据库④mongodb新闻项目实战

    python操作mongodb数据库④mongodb新闻项目实战 参考文档:http://flask-mongoengine.readthedocs.io/en/latest/ 目录: [root@n ...

  4. python操作三大主流数据库(13)python操作redis之新闻项目实战①新闻数据的导入

    1.新闻处理页面redis_news.py #coding:utf-8 import math import redis class RedisNews(object): def __init__(s ...

  5. python操作三大主流数据库(9)python操作mongodb数据库③mongodb odm模型mongoengine的使用

    python操作mongodb数据库③mongodb odm模型mongoengine的使用 文档:http://mongoengine-odm.readthedocs.io/guide/ 安装pip ...

  6. python操作三大主流数据库(8)python操作mongodb数据库②python使用pymongo操作mongodb的增删改查

    python操作mongodb数据库②python使用pymongo操作mongodb的增删改查 文档http://api.mongodb.com/python/current/api/index.h ...

  7. python操作三大主流数据库(7)python操作mongodb数据库①mongodb的安装和简单使用

    python操作mongodb数据库①mongodb的安装和简单使用 参考文档:中文版:http://www.mongoing.com/docs/crud.html英文版:https://docs.m ...

  8. python操作三大主流数据库(4)python操作mysql④python服务端flask和前端bootstrap框架结合实现新闻展示

    python操作mysql④python服务端flask和前端bootstrap框架结合实现新闻展示 参考文档http://flask.pocoo.org/docs/0.11/http://flask ...

  9. python操作三大主流数据库(3)python操作mysql③python操作mysql的orm工具sqlaichemy安装配置和使用

    python操作mysql③python操作mysql的orm工具sqlaichemy安装配置和使用 手册地址: http://docs.sqlalchemy.org/en/rel_1_1/orm/i ...

随机推荐

  1. golang channle 管道

    管道的使用介绍 现在要计算 1-N 的各个数的阶乘,并且把各个数的阶乘放入到 map 中.最后显示出来.要求使用 goroutine 完成 package main import ( "fm ...

  2. 【leetcode-84】 柱状图中最大的矩形

    (1pass,比较简单的hard) 给定 n 个非负整数,用来表示柱状图中各个柱子的高度.每个柱子彼此相邻,且宽度为 1 . 求在该柱状图中,能够勾勒出来的矩形的最大面积. 以上是柱状图的示例,其中每 ...

  3. stat/lstat函数使用

    1. 进程虚拟地址空间 2. stat函数 获取文件信息 #include <sys/types.h> #include <sys/stat.h> #include <u ...

  4. PHP7 学习笔记(十三)composer详解一

    摘要 从拷贝第三方代码到项目中(1994),到PEAR安装依赖包(1999),再到Composer兴起(2012),PHP社区经历了将近20年的探索.PHP这门古老的语言,也在不断的发展更新,在web ...

  5. overlay网络隔离实验失败记录

    按照 https://www.cnblogs.com/CloudMan6/p/7341487.html进行操作,实验结果与老师文章中的正好相反,不同 overlay 网络中的主机可以通信,验证部分见下 ...

  6. 基本数据类型转String,String转基本数据类型

    基本数据类型 --> 字符串 1.基本数据类型+"" String s = 5 + ""; 2.使用包装类的静态方法toString(参数),参数是要转化 ...

  7. 我的长大app开发教程第三弹:实现四个子页面绑定RadioButton

    在开始之前先上一张图 在上一节中我们实现了底部Button,这一弹我们要实现点击四个按钮分别切换到不同页面,我们可以把页面分为两部分,顶部栏和中间内容部分,我们可以通过线性布局包裹两部分内容,顶部栏又 ...

  8. C#生成Guid,SqlServer生成Guid

    https://www.cnblogs.com/che109/p/6808143.html工作中需要用到全球唯一标识符,在.net当中 微软已经为我们添加了此方法,我们只需要直接调用即可.代码如下: ...

  9. 23.Secondary Index

    一. Secondary Index(二级索引)1.1. Secondary Index 介绍 • Clustered Index(聚集索引) ◦ 叶子节点存储所有记录(all row data) • ...

  10. XXE攻防总结

    1. 前言与XML格式相同的web漏洞,比较广泛的共有xpath注入.xml注入.soap注入.XXE四种. 2. XML相关的介绍针对xml语言,要明白两个特性:合法性与合理性.所谓合法性,是指语法 ...