• 期末作品检查


    一、学期总结

    学习了一段时间的python,可以将本学期学习的内容大概可以分为三部分:前期基础的学习,中期网页的制作,后期网页的调整。

            前期:用Python进行简单算数计算。了解turtle库(海龟库),在此环境中练习条件、循环、函数定义的代码敲打,并画出了五角星、同心圆、太阳花、中国国旗等。随后便学习了字符串的基本操作,学会输入字符串,输出代码计算后的结果。还学习了凯撒密码、GDP格式化输出、九九乘法表等简单操作。利用python进行英文词汇统计,组合数据类型练习,用文件形式实现完成的英文词频统计、中文词频统计。利用datetime处理日期和时间,将字符串转化成imestamp与timedelta,同时了解管理信息系统概念与基础,理解数据存储的方式如字典、列表、元祖、集合,了解到Web是图形化的和易于导航的、与平台无关、是分布式的、是动态的、是交互的。

            中期:web的学习,学会认识URL,会观察网站网址,区分组成部分,练习用标签制作简单的页面,用html制作web页面,练习使用下拉列表选择框、无序列表、有序列表、定义列表。开始制作自己的导航条(HTML头部元素:<base>  定义了页面链接标签的默认链接地址。<style>  定义了HTML文档的样式。<link>  定义了一个文档和外部资源之间的关系)。练习样式表:行内样式表、内嵌样式表、外部样式表。分别练习定义三类选择器:HTML 选择器、CLASS 类选择器、ID 选择器。初步运用css做图片导航块,使用JS定义函数进行登录注册验证,完成登录与注册页面的前端,夜间模式的开启与关闭。

            后期:开始Flask项目,加载静态文件,父模板的继承和扩展,连接mysql数据库,创建用户模型,建立mysql和app的连接。通过用户模型,对数据库进行增删改查操作。完成注册功能,将界面的数据存到数据库,redirect重定向登录页。完成登录功能,用session记住用户名,像操作字典一样操作‘session’:增加用户名‘session[‘username’]’=username。登录之后更新导航,用上下文处理器app_context_processor定义函数,获取session中保存的值,返回字典,在父模板中更新导航,插入登录状态判断代码。完成注销功能,清除session。发布功能的实现,制作首页的显示列表,首页列表显示全部问答,完成问答详情页布局,从首页问答标题到问答详情页,完成评论功能,完成评论列表显示及排序,个人中心显示,个人中心标签页导航,完成个人中心—导航标签,实现搜索功能,最重要的是实现密码加密功能,还有模型分离与数据迁移,使代码更简洁更有保存用户的确定状态。

            总结Python+Flask+MysqL的web建设技术过程知识的梳理:

    学习Python需要掌握如下基础知识以及相关技能。

    1.Python基础知识(变量、语句、数据类型、数值类型、字符串、布尔类型、列表、字典、元组、条件语句、循环语句、函数、装饰器、面向对象、网络socket、爬虫)

    2.Python基础库(模块、包、系统模块、三方模块)

    3.python文件处理(读、写、执行、)

    4.python字符统计

    5.python数据排序

    6.学习python库、模块

    将多个代码块(按功能)定义到同一个文件中。别的文件中使用时则先导入模块,在调用模块内变量或函数。

    7.(1)模块学习方法:

    a.先知道有没有

    b.用的时候在查

    (2)模块命名要符合python变量的命名规范:

    a.建议全小写英文字母和数字

    b.避免与常用模块或第三方模块名称冲突

    3.包:

    将不同模块文件放在不同文件夹内,包文件夹下面需要有__init__.py文件用以声明该文件为Python包。

    使用时需要从包内导入模块后调用模块中变量和函数。

    4.正确的编程思路以及学习方法:

    计算机是人发明的,目的就是完成人的手动工作,跳不出人的思维。

    (1)弄清楚想要解决的问题。

    (2)思考自己如何去解决问题

    (3)画流程图(伪代码编写)

    (4)翻译成编程语言

    (5)运行调试代码

    重要:多抄、多写、多想、多问、多看、多听、多说

    (1)学习编程就是为了解决实际的问题,把自己在工作或学习中的重复工作程序化

    (2)谷歌和百度

    (3)加入开源社区(多看、多分享、多交流)

    (4)参加培训辅导(仔细听课、跟上课堂学习,有问题做记录,课后查阅资料或请求他人)

    (5)善于记录笔记,不断总结,查漏补缺。

    作为一个初学者,要多打代码,不然光看不练是写不出程序的,遇到问题就耐心解决,可以百度、或者上一些网站提问,都可以找到解决的方法,可以选择一个项目的教程视频跟着学下去,这样更加可以巩固我们在模块上的练习。以上是这学期的大致总结内容。

    下面 是本学期做的一个简单的页面,观察常用网页的HTML元素,在实际的应用场景中,用已学的标签模仿制作。用div,form制作登录页面,尽可能做得漂亮,实现了Python+Flask+MysqL的web建设,页面具有简单的注册、登陆发布文章、搜索文章等功能,在这里总结分享我本学期的学习成果:使用Flask框架搭建一个web service,并在其中加上一些简单的css,js,html等。由于本人是新手,如有错漏请见谅并欢迎大家批评指出。

    二、使用工具

    主要工具有:pycharm64.exe 、 MySQL 、 Navicat for MySQL

     

    三、完成基本的页面设计

    1.导航条(作为父模板)

    2.注册页面

    3.登录页面

    4.发布页面

    5.整个页面的整体布局

    四、实现页面及功能的所有的static文件、templates文件与py文件:

    五、Flask  概览

    from flask import Flask
    
    app = Flask(__name__)  # 创建Flask对象
    @app.route('/lin/')  # 跳转简单测试。
    def lin():
        return 'lin'
    
    if __name__ == '__main__':
        app.run(debug=True)
     
     

    六、加载静态文件、父模板与其他界面的继承

    1.用url_for加载静态文件,比如加载css, js, 文件

    <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/denglu.css') }}">
        <script src="{{ url_for('static',filename='js/denglu.js') }}"></script>

    2.继承和扩展

    把一些公共的代码放在父模板中,避免每个模板写同样的内容,子模板继承父模板

    {% extends 'daohang.html' %}

    父模板提前定义好子模板可以实现一些自己需求的位置及名称,子模板中写代码实现自己的需求

    {% extends 'daohang.html' %}
    
    {% block denglutitle %}登陆{% endblock %}
    {% block dengluhead %}
        
    {% block daohangbody %}

    七、数据库连接池

    1.创建数据库,数据库名为mis_db,将字符集设置为GBK格式,发布问答页,我在自己电脑上可以显示中文,在课室机上只能显示英文,设置为GBK格式后,就可以显示中文

    2.数据库mis_db中的user,fabu,comment表

    3.数据库配置信息config.py

    import os
    DEBUG = True
    
    SECRET_KEY = os.urandom(24)
    
    DIALECT = 'mysql'
    DRIVER = 'mysqldb'
    USERNAME = 'root'
    PASSWORD = '201506110137'
    HOST = '127.0.0.1'
    PORT = '3306'
    DATABASE = 'mis_db'
    
    # 配置和数据库的连接信息
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:201506110137@localhost/mis_db?charset=utf8'
    SQLALCHEMY_TRACK_MODIFICATIONS = False

    4.创建用户模型

    class User(db.Model):  # 创建类User
        __tablename__ = 'user'  # 类对应的表名user
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)  # autoincrement自增长
        username = db.Column(db.String(20), nullable=False)  # nullable是否为空
        _password = db.Column(db.String(200), nullable=False) #内部使用
        nickname = db.Column(db.String(20), nullable=True)
    
        @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 Fabu(db.Model):
        __tablename__ = 'fabu'
    
        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('fabu'))
    
    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'))
        fabu_id = db.Column(db.Integer, db.ForeignKey('fabu.id'))
        creat_time = db.Column(db.DateTime, default=datetime.now)
        detail = db.Column(db.Text, nullable=False)
        fabu = db.relationship('Fabu',backref=db.backref('comments',order_by=creat_time.desc))
        author = db.relationship('User', backref=db.backref('comments'))

    八、完成注册功能和登陆功能

    @app.route('/zhuce/', methods=['GET', 'POST'])
    def zhuce():
        if request.method == 'GET':
            return render_template('zhuce.html')
        else:
            username = request.form.get('user')  # post请求模式,安排对象接收数据
            password = request.form.get('pass')
            nickname = request.form.get('nickname')
            user = User.query.filter(User.username == username).first()  # 数据的查询,并判断
            if user:
                return u'该用户已存在'
            else:
                user = User(username=username, password=password, nickname=nickname)  # 将对象接收的数据赋到User类中,即存到数据库
                db.session.add(user)  # 数据的添加方法
                db.session.commit()
                return redirect(url_for('denglu'))  # redirect重定向
    @app.route('/denglu/', methods=['GET', 'POST'])
    def denglu():
        if request.method == 'GET':
            return render_template('denglu.html')
        else:
            username = request.form.get('user')  # post请求模式,安排对象接收数据
            password = request.form.get('pass')
            user = User.query.filter(User.username == username).first()  # 作查询,并判断
            if user:  # 判断用户名
                if user.check_password(password):# 判断密码
                    session['user'] = username  # 利用session添加传回来的值username
                    session.permanent = True  # 设置session过期的时间
                    return redirect(url_for('daohang'))
                else:
                    return u'用户密码错误'
            else:
                return u'用户不存在,请先注册'

    九、登录后更新导航

    1.用上下文处理器app_context_processor定义函数,把登陆时定义的session get进来

    @app.context_processor
    def mycontext():
        user = session.get('user')
        if user:
            return {'username': user}  # 包装到username,在所有html模板中可调用
        else:
            return {}  # 返回空字典,因为返回结果必须是dict

    2.在父模板中更新导航,利用if函数判断,插入登录状态判断代码

     {% if sessionusername %}
                        <li><a href="#" onclick="">{{ sessionusername }}</a></li>
                        <li><a href="{{ url_for('logout') }}" onclick=""><span class="glyphicon glyphicon-log-out"></span>
                            注销</a></li>
                    {% else %}
                        <li><a href="{{ url_for('denglu') }}" onclick=""><span class="glyphicon glyphicon-log-in"></span> 登陆</a>
                        </li>
                        <li><a href="{{ url_for('zhuce') }}" onclick=""><span class="glyphicon glyphicon-user"></span>
                            注册</a></li>
                    {% endif %}

    十、完成发布功能

    1.登录的装饰器

    ef loginFirst(fabu):
        @wraps(fabu)  # 加上wraps,它可以保留原有函数的__name__,docstring
        def wrapper(*args, **kwargs):  # 定义wrapper函数将其返回,用*args, **kwargs把原函数的参数进行传递
            if session.get('user'):  # 只有经过登陆,session才能记住并get到值
                return fabu(*args, **kwargs)
            else:
                return redirect(url_for('denglu'))
    
        return wrapper
    2.建立发布内容的对象关系映射
    class Fabu(db.Model):
        __tablename__ = 'fabu'
    
        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('fabu'))

    3.重定向到首页

    @app.route('/fabu/', methods=['GET', 'POST'])
    @loginFirst
    def fabu():
        if request.method == 'GET':
            return render_template('fabu.html')
        else:
            title = request.form.get('title')
            detail = request.form.get('detail')
            author_id = User.query.filter(
                User.username == session.get('user')).first().id
            fabu = Fabu(title=title, detail=detail, author_id=author_id)
            db.session.add(fabu)
            db.session.commit()
            return redirect(url_for('daohang'))

    十一、显示问答列表

    在首页点击问答标题,链接到相应详情页

    @app.route('/fabuview/<fabu_id>')
    def fabuview(fabu_id):
        fa = Fabu.query.filter(Fabu.id == fabu_id).first()  
        comments = Comment.query.filter(Comment.fabu_id == fabu_id).all()  
        return render_template('fabuview.html', fa=fa, comments=comments) 

    十二、实现发布评论,并显示评论区

    # 跳转评论
    @app.route('/comment/', methods=['POST'])
    @loginFirst  # 装饰器,跳转某页面之前先进行登录
    def comment():
        detail = request.form.get('pinglun')  # post请求模式,安排对象接收数据
        author_id = User.query.filter(User.username == session.get('user')).first().id
        fabu_id = request.form.get('fa_id')
        comment = Comment(detail=detail, author_id=author_id, fabu_id=fabu_id)  
        db.session.add(comment)  
        db.session.commit()  
        return redirect(url_for('fabuview', fabu_id=fabu_id))  

    十三、实现导航条中的搜索功能

    @app.route('/search/')
    def search():
        sousuo = request.args.get('sousuo')  
        fabus = Fabu.query.filter(
            or_(                              
                Fabu.title.contains(sousuo),  
                Fabu.detail.contains(sousuo)
            )
        ).order_by('-creat_time')
        return render_template('daohang.html', fabus=fabus) 

    十四、密码保护

    from werkzeug.security import generate_password_hash,check_password_hash
    
    _password = db.Column(db.String(200), nullable=False)   # 密码加密内部使用
    
        @property   # 定义函数,需要用属性时可以用函数代替
        def password(self):   # 密码加密外部使用
            return self._password
    
        @password.setter
        def password(self,row_password):   # 密码进来时进行加密,generate_password_hash是一个密码加盐哈希函数,生成的哈希值可通过check_password_hash()进行验证。
            self._password = generate_password_hash(row_password)
    
        def check_password(self,row_password):   # check_password_hash函数用于验证经过generate_password_hash哈希的密码。若密码匹配,则返回真,否则返回假。
            result = check_password_hash(self._password,row_password)
  • 相关阅读:
    一条痛并快乐的路
    Daily Scrum 11.1
    Daily Scrum 10.31
    Daily Scrum 10.30
    Daily Scrum 10.29
    Daily Scrum 10.28
    Daily Scrum 10.27
    (Alpha)Let's-Chronos分数分配规则
    Daily Scrum 10.26
    Daily Scrum 10.25
  • 原文地址:https://www.cnblogs.com/cch-1007/p/8109665.html
Copyright © 2020-2023  润新知