期末作品检查
一、学期总结
学习了一段时间的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)