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>
  • 相关阅读:
    Laravel 初始化
    ant design pro 左上角 logo 修改
    请求到服务端后是怎么处理的
    Websocket 知识点
    王道数据结构 (7) KMP 算法
    王道数据结构 (6) 简单的模式匹配算法
    王道数据结构 (4) 单链表 删除节点
    王道数据结构 (3) 单链表 插入节点
    王道数据结构 (2) 单链表 尾插法
    王道数据结构 (1) 单链表 头插法
  • 原文地址:https://www.cnblogs.com/reblue520/p/8509158.html
Copyright © 2011-2022 走看看