期末作品检查

一、学期总结

学习了一段时间的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)

posted on 2017-12-27 15:56  137陈楚洪  阅读(278)  评论(0编辑  收藏  举报

导航