zoukankan      html  css  js  c++  java
  • 期末作品检查

    1. 个人学期总结

          在这个学期里,在老师带领下,我们学习了管理信息系统这门课程。由一开始懵懵懂懂的概念知识到后面基本熟悉的上机操作,这都离不开老师对我们一步步的指导。在这个课程中我发现,跟随老师的步伐,做出一个界面并不代表什么,而是需要课后多加熟悉,上手操作,才能算是掌握这门课程的核心。

          在一开始接触Python,我们首先是做了一系列的基础练习,例如:简单输入输出交互、用户输入两个数字,计算并输出两个数字之和、输入半径,计算圆的面积等等一系列的简单代码训练,然后了解turtle库(海龟库)并在这个环境下进行基础训练,画出同切圆、同心圆、五角星,在慢慢由浅及深画黄色实心五角星、最后画国旗等等。再慢慢地由简单的多句代码实现绘画到利用条件、循环、函数定义减少代码数量实现绘画,其实就是利用简单的例子让我们熟悉Python环境,并从中学习到一些Python语言。接着就开始进行字符串的基本操作、凯撒密码、自制九九乘法表等等,再让我们进行中英文词频统计等组合数据类型练习。最后利用datetime处理日期和时间,将字符串转化成imestamp与timedelta,同时了解管理信息系统概念与基础,理解数据存储的方式如字典、列表、元祖、集合,了解到与Web相关的一些基础知识。让我们再简单的例子中熟悉并对Python产生兴趣,也在一些简单的例子里为之后的网页制作打下良好的基础。

          在中期,我们开始Web的各种练习,首先进行Web的基础训练,练习使用标签制作简单的页面。然后开始用div,form制作登录页面,练习使用下拉列表选择框,无序列表,有序列表,定义列表。也开始制作自己喜欢的导航条,其中包含HTML头部元素:<base>  定义了页面链接标签的默认链接地址、<style>  定义了HTML文档的样式文件、<link>  定义了一个文档和外部资源之间的关系;各种样式表;还有三类样式表。还有开始学习初步运用css做图片导航块,使用JS定义函数进行登录注册验证,完成登录与注册页面的前端HTML设计。到后面就开始了Flask框架制作网页的学习。

          在开始Flask项目开始后,我们学习了夜间模式的开启与关闭、父模板的制作,制作网站网页共有元素的父模板html,包括顶部导航,中间区块划分,底部导航等形成完整的一个html+css+js,把一些公共的代码放在父模板中,避免每个模板写同样的内容;然后学习了用url_for加载静态文件,用 render_template,用于创建一个Flask对象以及页面的跳转,进行父模板的继承和扩展,实现自己代码的需求。然后就开始安装与配置python3.6+flask+mysql数据库,建立mysql和app的连接,引入flask_sqlalchemy库进行数据库的关联映射,创建用户模型,对数据库进行增删改查操作。完成注册功能,将页面的数据存到数据库,redirect重定向登录页;完成登录功能,用session记住用户名,像操作字典一样操作‘session’:增加用户名‘session[‘username’]’=username。登录之后更新导航,用上下文处理器app_context_processor定义函数,获取session中保存的值,返回字典,在父模板中更新导航,插入登录状态判断代码。让登录后的导航显示登录用户的名字。接着完成注销功能,清除session。让注销后的导航栏上返回原来模样。后面完善发布功能,添加装饰器,需要用户发布前进行登录操作,登录后方可发布。建立发布内容的对象关系映射:class Question(db.Model),完成发布函数。把发布内容保存到数据库。然后返回到首页。然后制作首页的显示列表,数据库查询结果传递到前端页面 Question.query.all(),前端页面循环显示整个列表。完成问答详情页布局: 包含问答的全部信息评论区以往评论列表显示区。在首页点击问答标题,链接到相应详情页。做出一个整体框架后,我们开始完善里面的内容,显示评论次数、要求评论前登录、 尝试实现详情页面下的评论、密码保护、实现标签页导航等。后面基本上都是在完善这个项目了。

          在这一整个学期的学习过程中,也会遇到许许多多的问题,例如一开始怎么也把东西存放不进数据库,后来在一步步检查才发现没有在HTML中加上<from>标签;还有在某个单词拼写错误,在html里会用颜色的不同来报错,这种情况还较好处理,但在JS代码中是不会提示你哪里出错,所以在编写过程中要多加细心谨慎。还有在夜间模式里的JS文件中的两张图片的后缀不一样,但是在代码中后缀写的又是相同的,这样就不成功了。类似这种小错误还有很多,这就告诉我们在写代码的时候一定要细心谨慎,要多加检查。其实在每一个功能可以实现的时候,自己的成就感油然而生,所以我们多去练习多去运用,少用复制粘贴、投机取巧,我们才能在编程道路上越走越远。

    2、总结Python+Flask+MysqL的web建设技术过程

    在这学期里,我学习了使用Python的Flask框架+MysqL搭建简单的web项目,实现了具有登录注册发布评论功能等的简单页面。以下是我这学期的学习成果和学习经验:

    1、开始新建Flask项目

    ① 新建Flask项目。② 设置调试模式。③ 理解Flask项目主程序。④ 使用装饰器,设置路径与函数之间的关系。⑤ 使用Flask中render_template,用不同的路径,返回首页、登录员、注册页

    复制代码
    from flask import Flask,render_template
    
    app = Flask(__name__)
    
    
    @app.route('/')
    def sy():
        return render_template('sy.html')
    
    @app.route('/dl/')
    def dl():
        return render_template('dl.html')
    
    @app.route('/zc/')
    def zc():
        return render_template('zc.html')
    
    if __name__ == '__main__':
        app.run(debug=True)
    复制代码

    2、连接数据库

    ① 数据库配置信息config.py② 建立mysql和app的连接③ 创建用户模型

    config.py:

    import os
    
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:@127.0.0.1:3306/dianying?charset=utf8'
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    
    SECRET_KEY = os.urandom(24)

    建立连接+创建模型:

    复制代码
    from flask import Flask,request,render_template,redirect,url_for,session
    from werkzeug.security import generate_password_hash, check_password_hash
    from datetime import datetime
    from sqlalchemy import or_,and_
    from functools import wraps
    from flask_sqlalchemy import SQLAlchemy
    import config
    
    app = Flask(__name__)
    app.config.from_object(config)
    db = SQLAlchemy(app)
    
    
    
    
    class User(db.Model):
        __tablename__='user'
        id = db.Column(db.Integer,primary_key=TabError,autoincrement=True)
        username = db.Column(db.String(20),nullable=False)
        _password = db.Column(db.String(200), nullable=False)  # 内部使用
    
        @property
        def password(self):    #外部使用,取值
            return self._password
    
        @password.setter
        def password(self, row_password):    #外部使用,赋值
            self._password = generate_password_hash(row_password)
    
        def check_password(self, row_password):     #密码验证
            result = check_password_hash(self._password, row_password)
            return result
    
    class Question(db.Model):
        __tablename__='question'
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        title =db.Column(db.String(100), nullable=False)
        detail = db.Column(db.Text, nullable=False)
        creat_time=db.Column(db.DateTime,default=datetime.now)
        author_id = db.Column(db.Integer,db.ForeignKey('user.id'))
        author = db.relationship('User',backref=db.backref('question'))
    
    class Comment(db.Model):
        __tablename__='comment'
        id = db.Column(db.Integer,primary_key=True,autoincrement=True)
        author_id = db.Column(db.Integer,db.ForeignKey('user.id'))
        question_id = db.Column(db.Integer,db.ForeignKey('question.id'))
        creat_time = db.Column(db.DateTime,default=datetime.now)
        detail = db.Column(db.Text,nullable=False)
        question = db.relationship('Question',backref = db.backref('comments'))
        author = db.relationship('User',backref = db.backref('comments'))
    
    db.create_all()
    
    @app.route('/')
    def sy():
        context = {
            'questions': Question.query.all()
        }
        return render_template('sy.html', **context)
    
    if __name__ == '__main__':
        app.run(debug=True)
    复制代码

    数据库:

    3、导航条。

    制作一个自己的导航条,在导航条里有HTML头部元素:①<base> 定义了页面链接标签的默认链接地址 ②<style>定义了HTML文档的样式文件 ③<link>定义了一个文档和外部资源之间的关系,还有在这认识的CCS盒子模型。用来实现样式的美化,新建相应CSS文件,并链接到html文件中。还设计了相应的底部导航,底部导航是一些图片的相应友情链接。还有在完成登录之后,导航条也会随之发生改变。并要在主py文件上进行更新操作。

    导航HTML:

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>
            {% block title %}
            {% endblock %}
            ヾ(≧∇≦*)ゝ</title>
        <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/dh.css') }}">
         <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">   <!-- 用了bootstrap标准导航,导入其css样式-->
        <script src="{{ url_for('static',filename='js/dh.js') }}"></script>
    </head>
    {% block head %}
    {% endblock %}
    
    <nav class="navbar navbar-default" role="navigation">   <!-- class里的代码是显示导航框架 -->
           <div class="navbar-header">   <!-- class里的代码是让导航内容显示在同一行 -->
                    <a  href="http://127.0.0.1:5000/nr/"><img class="tubiao" id="tubiao" src="{{ url_for('static',filename='image/tb.jpg')}}"></a>
                </div>
                <form action="{{ url_for('cx') }}" method="get" class="navbar-form navbar-left" role="search">    <!-- class里的代码是让导航内容显示在一行上,并且navbar-left是让搜索框向左边靠-->
                    <div class="form-group">
                        <input type="text" class="form-control" placeholder="✍输入您感兴趣的" name="q">
                    </div>
                    <button type="submit" class="btn btn-default">查找</button>
                 </form>
                <ul class="nav navbar-nav navbar-right" id="myBody">
                    <li ><img class="tupian" id="myOnOff" onclick="myswitch()" src="{{ url_for('static',filename='image/sun.png')}}"></li>
                    <li><a href="{{ url_for('sy') }}"><span class="glyphicon .glyphicon-home"></span> 首页</a></li>
                    {% if username %}
                        <li><a href="{{ url_for('gr',user_id=session.get("userid"),tag=1) }}">{{ username }}</a></li>
                        <li><a href='{{ url_for('tc') }}'>退出</a></li>
                    {% else %}
                        <li><a href="{{ url_for('zc') }}"><span class="glyphicon glyphicon-user"></span> 注册</a></li>
                        <li><a href="{{ url_for('dl') }}"><span class="glyphicon glyphicon-log-in"></span> 登录</a></li>
                    {% endif %}
                        <li><a href="{{ url_for('fk') }}"><span class="glyphicon .glyphicon-pencil"></span> 发表影评</a></li>
    
                </ul>
    
            </div>
        </nav>
    
    <body id="myBody">
    {% block main %}
    
    {% endblock %}
    
    
    <nav class="dibu">
         <a class="daohang"  href="http://www.youku.com/"><img src="http://is4.mzstatic.com/image/thumb/Purple71/v4/71/04/5b/71045b9d-3687-f8cc-1457-7055b4e4ed44/source/512x512bb.png"width="50" height="50" alt="gzcc.cn"></a>
         <a class="daohang"  href="http://v.qq.com/?ptag=360.kuzhan"><img src="http://p2.img.cctvpic.com/nettv/newgame/cdn_pic/1956/mzm.zamlltui.png"width="50" height="50" alt="gzcc.cn"></a>
         <a class="daohang"  href="https://www.mgtv.com/"><img src="http://imga.mumayi.com/android/img_mumayi/2014/12/10/88/885578/icon/885578_5b92a.png"width="50" height="50" alt="gzcc.cn"></a>
         <a class="daohang"  href="http://www.iqiyi.com/?vfm=f_268_360d&fv=07668579fcb3b76994a863f602b0dce3"><img src="http://pic.paopaoche.net/up/2014-7/2014711152858.png"width="50" height="50" alt="gzcc.cn"></a>
         <a class="daohang"  href="http://www.pptv.com/"><img src="http://sr1.pplive.com/cms/19/45/23f41cc6977ca745cce69cdf92e4a1f9.png"width="50" height="50" alt="gzcc.cn"></a>
         <a class="daohang"  href="https://tv.sohu.com/"><img src="http://www.d9soft.com/uploadfile/2013/0718/20130718061513909.png"width="50" height="50" alt="gzcc.cn"></a>
            <p>Copyright ©2017 silky-L</p>
    </nav>
    </body>
    </html>
    复制代码

    CSS文件:

    复制代码
    .tupian{
        50px;
        height:50px;
    }
    .tubiao{
        50px;
        height:50px;
    }
    .dibu{
        100%;
        background-color:gainsboro;
        position:fixed;
        bottom:0;/**距离底部为0*/left:0;z-index:1;
        text-align:center;
    }
    复制代码

    效果如图:

    头部导航条:

    底部导航条:

     登录后的导航条:

    4、开关灯功能。

    在导航条里有一个开关灯的按钮,要是要这个按钮的功能实现,就要上一个JS文件。JS文件用来定义开关切换函数,在HTML里面用onclick函数调用。在导航的HTML里用url_for加载静态文件<script src="{{ url_for('static',filename='js/dh.js') }}"></script>。HTML+CSS+JS这三个文件组成了一个父模板,在其他页面也可以继承这个父模板,不用每一个页面都去制作一个导航条。

    JS文件:

    复制代码
    function myswitch() {
                var oBody = document.getElementById("myBody");
                var oOnoff = document.getElementById("myOnOff");
                if(oOnoff.src.match("sun")){
                    oOnoff.src="../static/image/moon.jpg";
                    oBody.style.background="black";
                    oBody.style.color ="white";
                }else{
                    oOnoff.src="../static/image/sun.png";
                    oBody.style.background="white";
                    oBody.style.color ="black";
                }
            }
    复制代码

    效果如图:

    开灯:

    关灯:

    5、注册与登录页面。

    注册与登录页面也有三个文件组成,HTML+CSS+JS。在注册与登录页面上还增加了三种输出数据的方式:① 使用 document.write() 方法将内容写到 HTML 文档中。② 使用 window.alert() 弹出警告框。③ 使用 innerHTML 写入到 HTML 元素。在JS文件里定义JavaScript 函数。并在主py文件里进行更新操作。

    在注册页面里,

    1 js文件: onclick函数return True时才提交表单,return False时不提交表单。

    2 html文件:

    <form>中设置 action和method="post"

    <input> 中设置 name

    3 主py文件中:

    from flask import  request, redirect, url_for

    @app.route('/regist/', methods=['GET', 'POST’])

    def regist():

       if request.method == 'GET':

            return render_template('regist.html')

       else:

            username = request.form.get(‘username’)#获取form中的数据

            判断用户名是否存在:存在报错

            不存在,存到数据库中

    5 redirect重定向到登录页

    注册HTML:

    复制代码
    {% extends 'dh.html' %}
    {% block title %}
    注册
    {% endblock %}
    {% block main %}
        <link rel="stylesheet" type="text/css" href="../static/css/zc.css">
        <script src="../static/js/zc.js"></script>
    </head>
    <body  class="zcbg" background="{{ url_for('static',filename='../static/image/zcbg.jpg') }}">
    
    <div class="box" >
        <form action="{{url_for('zc')}}" method="post">
        <div class="container" style=" 400px"align="center">
        <div class="dl"><h2 align="center" style="margin-bottom: 0;  400px">注 ✉ 册</h2></div>
        <div class="content" style="">
        <div class="xx" align="center">
            <p> </p><br>
            用户账号:<input id="name" type="name"placeholder="请输入用户名" name="name"><br>
            输入密码:<input id="password" type="password"placeholder="请输入密码" name="password"><br>
            确认密码:<input id="againpass" type="password"placeholder="请再次输入密码" name="againpass">
            <p> </p>
            </div>
            <div id="error_box"><br></div>
            <p>  </p>
          <div class="an" >
             <button onclick="myLogin()">注册</button>
             <button type="button" onclick=window.alert("是否取消注册!")>取消</button>
    
             </div>
    
        </div>
         </div>
        </form>
        </div>
    
    </body>
    </html>
    
    {% endblock %}
    复制代码

    JS文件:

    复制代码
    function myLogin() {
            var oUname = document.getElementById("name");
            var oError = document.getElementById("error_box");
            var opassword = document.getElementById("password");
            var oAgainname = document.getElementById("againpass");
    
            oError.innerHTML="<br>"
            //name
            if(oUname.value.length<6||oUname.value.length>20){
    
                oError.innerText="☞用户名请输入6-20个字符";
                return false;
                }
                else if ((oUname.value.charCodeAt(0)>=48)&&oUname.value.charCodeAt(0)<=57){
                    oError.innerText="✘用户名首字母不能为数字";
                    return false;
            }
            else for(var i=0; i<oUname.value.length; i++){
                    if((oUname.value.charCodeAt(i)<48)||(oUname.value.charCodeAt(i)>57) && (oUname.value.charCodeAt(0)<97) || (oUname.value.charCodeAt(0)>122)){
                        oError.innerHTML="✘用户名只能是小写字母与数字";
                        return false;
                    }
            }
            //password
            if(opassword.value.length<6||oAgainname.value.length>20){
    
                oError.innerText="☛密码请输入6-20个字符内";
                return false;
            }
            else if (password.value!= againpass.value) {
                oError.innerHTML = "✘两次密码不一致"
                return false;
            }
            window.alert("✌注册成功!\(^o^)/YES!")
            return true;
            }
    复制代码

    效果如图:

    登录功能完成:

    1 js:设置:return

    2 html:设置:form、input、onclick="return fnLogin()"

    3 py:

    @app.route设置methods:GET、POST

    读取表单数据、查询数据库、用户名密码对、记住用户名、跳转到首页、用户名密码不对、提示相应错误。

    session:从`flask`中导入`session`、设置`SECRET_KEY`、操作字典一样操作`session`:增加用户名`session['username']=`username

    登录HTML:

    复制代码
    {% extends 'dh.html' %}
    {% block title %}
    登录
    {% endblock %}
    {% block main %}
        <link rel="stylesheet" type="text/css" href="../static/css/dl.css">
        <script src="../static/js/dl.js"></script>
    </head>
    <body  class="bg" background="{{ url_for('static',filename='../static/image/dlbg.jpg') }}"> {# 背景图 #}
    
    <div class="box" >
        <form action="{{url_for('dl')}}" method="post">
        <div class="container" style=" 400px"align="center">
        <div class="dl"><h2 align="center" style="margin-bottom: 0;400px">✉登  录✉</h2></div>{# 登录标题 #}
        <div class="content">   {#登录框#}
        <div class="xx" align="center">
            <p> </p>
            账  户:<input id="name" type="text"placeholder="请输入用户名" name="name"><br>
            密  码:<input id="password" type="password"placeholder="请输入密码" name="password">
            <p> </p>
            </div>
            <div id="error_box"><br></div>
            <p>  </p>
          <div class="an" >
             <button onclick="myLogin()">登录</button>
             <button type="button" onclick=window.alert("是否取消登录!")>取消</button>
    
             </div>
    
        </div>
         </div>
        </form>
    </div>
    </body>
    </html>
    
    {% endblock %}
    复制代码

    JS文件:

    复制代码
    function myLogin() {
            var oUname = document.getElementById("name");
            var oError = document.getElementById("error_box");
            var opassword = document.getElementById("password");
            oError.innerHTML="<br>"
            //name
            if(oUname.value.length<6||oUname.value.length>20){
                    oError.innerText="☞用户名请输入6-20个字符";
                    return false;
                }
                else if ((oUname.value.charCodeAt(0)>=48)&&oUname.value.charCodeAt(0)<=57){
                oError.innerText="✘用户名首字母不能为数字";
                    return false;
            }
            else for(var i=0; i<oUname.value.length; i++){
                    if((oUname.value.charCodeAt(i)<48)||(oUname.value.charCodeAt(i)>57) && (oUname.value.charCodeAt(0)<97) || (oUname.value.charCodeAt(0)>122)){
                        oError.innerHTML="✘用户名只能是小写字母与数字";
                        return false;
                    }
            }
            //password
            if(opassword.value.length<6||opassword.value.length>20){
                    oError.innerText="☛密码请输入6-20个字符内";
                    return false;
                }
             return true;
             }
    复制代码

     效果如图:

    7、发布页面。

    制作带label的文本输入区域的页面,实现发布功能。最后要在主py文件里进行更新操作。

    1 在主py文件里编写要求登录的装饰器

    from functools import wraps

    def loginFirst(func): #参数是函数

    @wraps(func)

          def wrapper(*args, ** kwargs): #定义个函数将其返回

              #要求登录

              return func(*args, ** kwargs)

          return wrapper #返回一个函数

    2 应用装饰器,要求在发布前进行登录,登录后可发布。

    @app.route('/question/',methods=['GET','POST'])
    @loginFirst
    def question():

    3 建立发布内容的对象关系映射。

    class Question(db.Model):

    4 完成发布函数。

    5 保存到数据库。

    6 重定向到首页。

    HTML:

    复制代码
    {% extends 'dh.html' %}
    {% block title %}
       反馈页面
    {% endblock  %}
    {% block head %}
            <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='../static/css/fk.css') }}">
    {% endblock  %}
    {% block main %}
        <body>
    <div class="question-feedback">
    <h2> 影评发布 </h2>
    <form action="{{ url_for('fk') }}" method="post" >
       <div class="question-control">
           <div>
                <label for="question">标题:</label>
                <br>
                <textarea class="form-control" rows="6" id="questionTitle" placeholder="请输入影评标题"
                          style="height: 50px" name="title" ></textarea>
            </div>
           <div>
                <label for="questionDetail">评论:</label>
                <br>
                <textarea class="form-control" rows="6" id="questionDetail" placeholder="请描述你对电影的感受"
                          style="height: 130px" name="detail"></textarea>
           </div>
           <input type="checkbox" id="c1">发布影评<br>
       </div>
        <div class="submit-button">
           <br>
           <button type="submit" style="float:right" id="submit-button">发送</button>
        </div>
    </form>
    </div>
        </body>
    {% endblock  %}
    复制代码

    效果如图:

    8、首页列表。

    在影评发布后,会显示在首页的列表上。1 首页列表显示全部问答:将数据库查询结果传递到前端页面 Question.query.all() 2 前端页面循环显示整个列表。 3 问答排序。最后并在主py文件上进行更新操作。

    首页HTML:

    复制代码
    {% extends 'dh.html' %}
    {% block title %}
        首页
    {% endblock %}
    {% block head %}
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
        <link rel="stylesheet" type="text/css" href="../static/css/sy.css">
    {% endblock %}
    {% block main %}
        <body  class="sybg" background="{{ url_for('static',filename='../static/image/sybg.jpg') }}">
        <div class="nr-box">
            <ul class="list-group">
                {% for foo in questions %}
                <li class="list-group-item">
                <img style=" 30px" src="{{ url_for('static',filename='../static/image/tx.jpg') }}" alt="64">
                    <a href="{{ url_for('gr',user_id=foo.author.id,tag=1) }}">{{ foo.author.username }}</a><br>
                     <a href="{{ url_for('xq',question_id = foo.id) }}">题目:{{ foo.title }}</a><br>
                    <p>影评:{{ foo.detail }}</p><br>
                    <span class="badge" style="margin-left: 60%">{{ foo.creat_time }}发布时间</span>
                    <p style="margin-left: 25%"></p>
                </li>
                {% endfor %}
            </ul>
        </div>
        </body>
    {% endblock %}
    复制代码

    效果如下:

     

     9、详情页面。

    制作详情页面,详情页布局:1 包含问答的全部信息 2 评论区 3 以往评论列表显示区。最后在主py文件上进行更新操作。

    还要制作首页标题的标签做带参数的链接:{{ url_for('detail',question_id = foo.id) }}

    1 在详情页将数据的显示在恰当的位置。 

    {{ ques.title}}
    {{ ques.id  }}{{  ques.creat_time }}

    {{ ques.author.username }} 
    {{ ques.detail }}

    2 建立评论的对象关系映射:

    class Comment(db.Model):
        __tablename__='comment'

    3 尝试实现发布评论。

    HTML:

    复制代码
    {% extends 'dh.html' %}
    {% block title %}
        反馈详情
    {% endblock  %}
    {% block head %}
            <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='../static/css/xq.css') }}">
    {% endblock  %}
    {% block main %}
       <div class="page-header">
       <h3>问题:{{ ques.title }}<br>
           <small>作者:{{ ques.author.username }}<br>
               <span class="">
                   发布时间:{{ ques.creat_time }}
               </span></small></h3>
        <p class="lead">详情:{{ ques.detail }} </p>
           <form role="form" action="{{ url_for('comment') }}" method="post">
        <div class="form-group">
            <textarea  name="new_comment" class="form-control" rows="6" id="questionTitle" placeholder="请写下你的评论" style="height: 100px" ></textarea>
            <input name="question_id" type="hidden" value="{{ ques.id }}">
            <br>
               <button type="submit" style="float:right" id="submit-button">发送</button>
        </div>
       </form></div>
        <div class="pl-box">
           <h4>评论区:
           ({{ ques.comments|length }})</h4><br>
    
        <ul class="list-group">
                {% for ques in ques.comments %}
                <li class="list-group-item">
                <img style=" 30px" src="{{ url_for('static',filename='../static/image/tx.jpg') }}" alt="64">
                    <a href="{{ url_for('gr',user_id=ques.author.id,tag=1) }}">{{ ques.author.username }}</a><br>
                    <p>评论详情:{{ ques.detail }}</p><br>
                    <span class="badge" style="margin-left: 60%">{{ ques.creat_time }}评论时间</span>
                    <p style="margin-left: 25%"></p>
                </li>
                {% endfor %}
            </ul>
        </div>
    
    
    {% endblock %}
    复制代码

    效果如图:

    10、个人中心

    先新建一个个人中心的导航页,个人中心的页面需要继承总的导航条。然后建立全部文章、全部评论、个人信息三个子页面继承个人中心的导航页。1 userbase.html,用<ul ><li role="presentation"> 实现标签页导航。2 让userbase.html继承父模板。然后三个子页面分别继承个人中心的导航页面。最后在主py文件中进行更新操作。

    个人中心导航HTML:

    复制代码
    {% extends 'dh.html' %}
    {% block title %}
       个人中心
    {% endblock  %}
      {% block head %}
        <style>
            .nav_ul li{
                float: left;
                list-style: none;
                margin: 10px;
                border-bottom: antiquewhite;
            }
        </style>
    {% endblock %}
    
    {% block main %}
        <ul class="nav nav-tabs">
            <li role="presentation"><a href="{{ url_for('gr', user_id = user.id,tag='1') }}">全部问答</a></li>
            <li role="presentation"><a href="{{ url_for('gr',user_id = user.id,tag='2') }}">全部评论</a></li>
            <li role="presentation"><a href="{{ url_for('gr',user_id = user.id,tag='3') }}">个人信息</a></li>
    
        </ul>
        {% block user %}{% endblock %}
    {% endblock %}
    复制代码

    全部文章HTML:

    复制代码
    {% extends 'gr-dh.html' %}
    
    {% block user %}
        <div class="page-header">
            <h3><span class="glyphicon glyphicon-user"  aria-hidden="true"></span>{{ username }}<br>
                <small>全部文章<span class="badge"></span></small>
            </h3>
            <ul class="list-group" style="margin: 10px">
                {% for ques in question %}
                    <li class="list-group-item" style="word-wrap:break-word;">
                        <span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span>
                        <a href="#">{{ ques.author.username }}</a>
                        <span class="badge" style="margin-left: 60%">{{ ques.creat_time }}发布时间</span>
                        <p>{{ ques.detail }}</p>
                    </li>
                {% endfor %}
            </ul>
        </div>
    
    {% endblock %}
    复制代码

    全部评论HTML:

    复制代码
    {% extends 'gr-dh.html' %}
    
    {% block user %}
        <div class="page-header">
            <h3><span class="glyphicon glyphicon-user"  aria-hidden="true"></span>{{ username }}<br>
                <small>全部评论<span class="badge"></span></small>
            </h3>
            <ul class="list-group" style="margin: 10px">
                {% for ques in comments %}
                    <li class="list-group-item">
                        <span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span>
                        <a href="#">{{ ques.author.username }}</a>
                        <span class="badge">{{ ques.create_time }}</span>
                        <p>{{ ques.detail }}</p>
                    </li>
                {% endfor %}
            </ul>
        </div>
    
    {% endblock %}
    复制代码

    个人信息HTML:

    复制代码
    {% extends 'gr-dh.html' %}
    
    {% block user %}
        <div class="page-header">
            <h3><small>个人信息<span class="badge"></span></small></h3>
            <ul class="list-group" style=" ">
                <li class="list-group-item">用户:{{ username }}</li>
                <li class="list-group-item">编号:{{ user.id }}</li>
                <li class="list-group-item">文章数:{{ question|length }}</li>
                <li class="list-group-item">评论数:{{ comments|length }}</li>
                <p>     </p>
            </ul>
        </div>
    
    {% endblock %}
    复制代码

    效果如图:

    11、搜索功能。

    修改父模板页面中搜索输入框所在的<form action="{{ url_for('search') }}" method="get">、<input name="q" type="text" placeholder="请输入关键字">

    完成视图函数search()、获取搜索关键字:q = request.args.get('q’)、条件查询:qu = Question.query.filter(Question.title.contains(q)).order_by('-creat_time’)

    加载查询结果:return render_template('index.html', question=qu)

    组合条件查询:from sqlalchemy import or_, and_ 

    主py文件:

    复制代码
    @app.route('/cx/')
    def cx():
        qu = request.args.get('q')
        ques = Question.query.filter(
            or_(
                Question.title.contains(qu),
                Question.detail.contains(qu)
            )
        ).order_by('-creat_time')
        return render_template('sy.html',questions = ques)
    复制代码

    导航页HTML:

     <form action="{{ url_for('cx') }}" method="get" class="navbar-form navbar-left" role="search">
                    <div class="form-group">
                        <input type="text" class="form-control" placeholder="✍输入您感兴趣的" name="q">
                    </div>
                    <button type="submit" class="btn btn-default">查找</button>
                 </form>

    12、密码保护。

    1 更新User对象,设置对内的_password

    class User(db.Model):

        __tablename__ = 'user' 

        _password = db.Column(db.String(200), nullable=False) #内部使用 

    2 编写对外的password

    from werkzeug.security import generate_password_hash, check_password_hash

        @property

        def password(self):  #外部使用,取值

            return self._password

        @password.setter

        def password(self, row_password):#外部使用,赋值

            self._password = generate_password_hash(row_password)

     3 密码验证的方法:

        def check_password(self, row_password): #密码验证

            result = check_password_hash(self._password,row_password)

            return result 

    4 登录验证:

            password1 = request.form.get('password')

            user = User.query.filter(User.username == username).first()

            if user:

                if user.check_password(password1):

     主py文件:

    复制代码
    class User(db.Model):
        __tablename__='user'
        id = db.Column(db.Integer,primary_key=TabError,autoincrement=True)
        username = db.Column(db.String(20),nullable=False)
        _password = db.Column(db.String(200), nullable=False)  # 内部使用
    
        @property
        def password(self):    #外部使用,取值
            return self._password
    
        @password.setter
        def password(self, row_password):    #外部使用,赋值
            self._password = generate_password_hash(row_password)
    
        def check_password(self, row_password):     #密码验证
            result = check_password_hash(self._password, row_password)
            return result
    
    
    @app.route('/dl/',methods=['GET','POST'])
    def dl():
        if request.method == 'GET':
            return render_template("dl.html")
        else:
            usern = request.form.get('name')
            password = request.form.get('password')
            user = User.query.filter(User.username == usern).first()
            if user:
                if user.check_password(password):
                    session['user'] = usern
                    session['userid'] = user.id
                    session.permanent = True
                    return redirect(url_for('sy'))
                else:
                    return '密码错误(〃>皿<)'
            else:
                return '用户不存在┌(。Д。)┐'
    复制代码

    效果如图:

    13、总的py文件:

    复制代码
    from flask import Flask,request,render_template,redirect,url_for,session
    from werkzeug.security import generate_password_hash, check_password_hash
    from datetime import datetime
    from sqlalchemy import or_,and_
    from functools import wraps
    from flask_sqlalchemy import SQLAlchemy
    import config
    
    app = Flask(__name__)
    app.config.from_object(config)
    db = SQLAlchemy(app)
    
    
    
    
    class User(db.Model):
        __tablename__='user'
        id = db.Column(db.Integer,primary_key=TabError,autoincrement=True)
        username = db.Column(db.String(20),nullable=False)
        _password = db.Column(db.String(200), nullable=False)  # 内部使用
    
        @property
        def password(self):    #外部使用,取值
            return self._password
    
        @password.setter
        def password(self, row_password):    #外部使用,赋值
            self._password = generate_password_hash(row_password)
    
        def check_password(self, row_password):     #密码验证
            result = check_password_hash(self._password, row_password)
            return result
    
    class Question(db.Model):
        __tablename__='question'
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        title =db.Column(db.String(100), nullable=False)
        detail = db.Column(db.Text, nullable=False)
        creat_time=db.Column(db.DateTime,default=datetime.now)
        author_id = db.Column(db.Integer,db.ForeignKey('user.id'))
        author = db.relationship('User',backref=db.backref('question'))
    
    class Comment(db.Model):
        __tablename__='comment'
        id = db.Column(db.Integer,primary_key=True,autoincrement=True)
        author_id = db.Column(db.Integer,db.ForeignKey('user.id'))
        question_id = db.Column(db.Integer,db.ForeignKey('question.id'))
        creat_time = db.Column(db.DateTime,default=datetime.now)
        detail = db.Column(db.Text,nullable=False)
        question = db.relationship('Question',backref = db.backref('comments'))
        author = db.relationship('User',backref = db.backref('comments'))
    
    #db.create_all()
    
    # #增加
    # user = User(username='123456',password = '456789')
    # db.session.add(user)
    # db.session.commit()
    #
    # #查询
    # user =User.query.filter(User.username =='abcdef').first()
    # print(user.username,user.password)
    #
    # #修改
    # user =User.query.filter(User.username =='123456').first()
    # user.password='abcdef'
    # print(user.username,user.password)
    # db.session.commit()
    #
    # #删除
    # user =User.query.filter(User.username =='123456').first()
    # print(user.username,user.password)
    # db.session.delete(user)
    # db.session.commit()
    
    @app.route('/')
    def sy():
        context = {
            'questions': Question.query.all()
        }
        return render_template('sy.html', **context)
    
    @app.route('/xq/<question_id>')
    def xq(question_id):
        quest = Question.query.filter(Question.id == question_id).first()
        return render_template('xq.html',ques = quest)
    
    def loginFirst(func):
        #行动前需要登录,定义装饰器
        @wraps(func)
        def wrapper(*args,**kwargs):
            if session.get('user'):
                return func(*args,**kwargs)
            else:
                return redirect(url_for('dl'))
        return wrapper
    
    @app.route('/comment/', methods=['POST'])
    @loginFirst
    def comment():
        comment = request.form.get('new_comment')
        ques_id = request.form.get('question_id')
        author_id = User.query.filter(User.username == session.get('user')).first().id
        comm = Comment(detail=comment, author_id=author_id, question_id=ques_id )
        db.session.add(comm)
        db.session.commit()
        return redirect(url_for('xq', question_id=ques_id))
    
    
    @app.route('/gr/<user_id>/<tag>')
    @loginFirst
    def gr(user_id,tag):
        user=User.query.filter(User.id==user_id).first() #把信息存放到数据库里面
        context={
            'username':user.username,
            'question':user.question,
            'comments':user.comments,
            'user':user
        }
        if tag == '1':
            return render_template('wd.html',**context) #输出显示数据库里的信息
        elif tag == '2':
            return render_template('pl.html',**context)
        else:
            return render_template('zx.html', **context)
    
    @app.route('/nr/')
    def nr():
        return render_template('nr.html')
    
    
    @app.route('/dl/',methods=['GET','POST'])
    def dl():
        if request.method == 'GET':
            return render_template("dl.html")
        else:
            usern = request.form.get('name')
            password = request.form.get('password')
            user = User.query.filter(User.username == usern).first()
            if user:
                if user.check_password(password):
                    session['user'] = usern
                    session['userid'] = user.id
                    session.permanent = True
                    return redirect(url_for('sy'))
                else:
                    return '密码错误(〃>皿<)'
            else:
                return '用户不存在┌(。Д。)┐'
    
    @app.context_processor
    def mycontext():
        usern=session.get('user')
        if usern:
            return {'username':usern}
        else:
            return{}
    
    @app.route('/zc/',methods=['GET','POST'])
    def zc():
        if request.method == 'GET':
            return render_template("zc.html")
        else:
            usern = request.form.get('name')
            password = request.form.get('password')
            user = User.query.filter(User.username == usern).first()
            if user:
                return '用户名已存在┗|*`0′*|┛ '
            else:
                user1 = User(username=usern, password=password)
                db.session.add(user1)
                db.session.commit()
                return redirect(url_for('dl'))
    
    @app.route('/tc/')
    def tc():
        session.clear();
        return redirect(url_for('sy'))
    
    def loginFirst(func):
        #行动前需要登录,定义装饰器
        @wraps(func)
        def wrapper(*args,**kwargs):
            if session.get('user'):
                return func(*args,**kwargs)
            else:
                return redirect(url_for('dl'))
        return wrapper
    
    @app.route('/fk/',methods=['GET','POST'])
    @loginFirst
    def fk():
        if request.method == 'GET':
            return render_template('fk.html')
        else:
            title = request.form.get('title')
            detail = request.form.get('detail')
            author_id = User.query.filter(User.username == session.get('user')).first().id
            question = Question(title=title, detail=detail, author_id=author_id)
            db.session.add(question)  # 数据库,添加操作
            db.session.commit()
        return redirect(url_for('sy'))
    
    @app.route('/cx/')
    def cx():
        qu = request.args.get('q')
        ques = Question.query.filter(
            or_(
                Question.title.contains(qu),
                Question.detail.contains(qu)
            )
        ).order_by('-creat_time')
        return render_template('sy.html',questions = ques)
    
    if __name__ == '__main__':
        app.run(debug=True)
    复制代码

    总结:以上就是本学期使用Python的Flask框架+MysqL完成简单的网页。Flask是一个使用Python编写的轻量级 Web 应用框架。感觉这一门科目是很有趣的,它运用的语言知识简洁易懂,当成功运行出来的时候,满满的成就感。虽然还是有很多地方还不是很理解,但是只要往后多了解,多练习,就会更好地掌握这些知识。

  • 相关阅读:
    React在componentDidMount里面发送请求
    React 术语词汇表
    React里受控与非受控组件
    React和Vue等框架什么时候操作DOM
    【LeetCode】79. Word Search
    【LeetCode】91. Decode Ways
    【LeetCode】80. Remove Duplicates from Sorted Array II (2 solutions)
    【LeetCode】1. Two Sum
    【LeetCode】141. Linked List Cycle (2 solutions)
    【LeetCode】120. Triangle (3 solutions)
  • 原文地址:https://www.cnblogs.com/qisq/p/8206243.html
Copyright © 2011-2022 走看看