zoukankan      html  css  js  c++  java
  • python操作三大主流数据库(6)python操作mysql⑥新闻管理后台功能的完善(增、ajax异步删除新闻、改、查)

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

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

    目录结构:

    [root@node1 mysql_version03]# tree -L 3
    .
    ├── flask_news.py
    ├── forms.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
        ├── 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>
  • 相关阅读:
    Bluetooth GATT介绍
    Bluetooth ATT介绍
    Bluetooth GAP介绍
    Bluetooth Low Energy介绍
    CC2540介绍
    DBus介绍
    802.11 MAC层
    802.11介绍
    Python资料
    Bluedroid之GKI
  • 原文地址:https://www.cnblogs.com/reblue520/p/8509158.html
Copyright © 2011-2022 走看看