期末作品检查
1.个人学期总结
Python作为近几年流行起来的语言, 是一种不受局限、跨平台的开源编程语言,它功能强大且简单易学。因而得到了广泛应用和支持。 Python作为动态语言更适合初学编程者。Python可以让初学者把精力集中在编程对象和思维方法上,而不用去担心语法、类型等等外在因素。Python的库很庞大。它可以帮助处理各种工作,包括正则表达式、文档生成、单元测试、线程、数据库、网页浏览器、CGI、FTP、电子邮件、XML、XML-RPC、HTML、WAV文件、密码系统、GUI(图形用户界面)、Tk和其他与系统有关的操作。这被称作Python的“功能齐全”理念。除了标准库以外,还有许多其他高质量的库,如wxPython、Twisted和Python图像库等等。
第一次接触python,我们首先学的是简单的输出输入计算,到引入 turtle库,绘制多种多样的图形,接着学习了字符串基本操作,进行了中英文词频统计,直到最后我们学习了Python+Flask+MysqL的web建设,做出了自己的网页。通过本学对python基础知识的学习,发现其实python语言比起其他语言的学习要好入手很多。比如python有很库、获取数据方便、数据运算方便、表达的语句简而易懂、与其他语言交互很方便、信息处理也很方便。总的来说,python语言非常简单,阅读一个良好的Python程序就感觉像是在读英语一样,尽管这个对英语的要求非常严格!Python的这种伪代码本质是它最大的优点之一。它使你能够专注于解决问题而不是去搞明白语言本身。在当今的大数据时代,更是需要这种易懂、方便学习的编程语言来处理大数据和得出最优的结论出来。但是python也有缺点,很多时候不能将程序连写成一行,如import sys;for i in sys.path:print i。而perl和awk就无此限制,可以较为方便的在shell下完成简单程序,不需要如Python一样,必须将程序写入一个主.py文件。既是优点也是缺点,python的开源性是的Python语言不能加密。总体来说,python语言还算是比较优秀的,吸引的人才多,项目也多。
2.总结Python+Flask+MysqL的web建设技术过程
下面以简单的页面设计为例简单介绍Python+Flask+MysqL的web建设技术过程
一、首先,创建并连接数据库,代码如下:
import os DEBUG = True SECRET_KEY = os.urandom(24) SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:@localhost:3306/xingzuo?charset=utf8' SQLALCHEMY_TRACK_MODIFICATTONS = False
在数据库中创建所需要的表:
class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True, autoincrement=True) username = db.Column(db.String(100), nullable=False) _password = db.Column(db.String(500), 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) create_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')) create_time = db.Column(db.DateTime, default=datetime.now) detail = db.Column(db.Text, nullable=False) question = db.relationship('Question',backref=db.backref('comments',order_by=create_time.desc)) author = db.relationship('User',backref=db.backref('comments')) db.create_all()
创建得到的数据库表如下:



二、建一个父模板,其中导航条如下:

<nav class="navbar navbar-default" role="navigation"> <div class="container-fluid"> <div class="navbar-header"> <a class="navbar-brand" style="color: cornflowerblue;font-weight: bold;font-size: 30px;font-family: 华文行楷;">星座屋</a> <a class="navbar-brand" href="{{ url_for('shouye') }}"style="color: purple;background-color: white;font-size: 25px;margin-top:10px">首页</a> <a class="navbar-brand" href="{{ url_for('wenda') }}"style="color: rebeccapurple;background-color: white;font-size: 20px;margin-top:10px">星座问答区</a></div> <form action="{{ url_for('search') }}" class="navbar-form navbar-left" role="search"method="get"> <div class="form-group"><input type="text" name="q" class="form-control" placeholder="输入您感兴趣的"><button type="submit" class="btn btn-default" style="width: 70px">查询</button></div> </form> <ul class="nav navbar-nav navbar-right"> {% if username %} <li><a href="{{ url_for('usercenter',user_id = session.get('id'),tag=3)}}" style="background-color: white">{{ session.get('user') }}</a></li> <li><a href="{{url_for('logout') }}" style="background-color: white"><span class="glyphicon glyphicon-user"></span> 注销</a></li> <li><a href="{{ url_for('usercenter',user_id = session.get('id'),tag=3)}}" style="background-color: white"><span class="glyphicon glyphicon-log-in"></span> {{username }}</a></li> {% else %} <li><a href="{{ url_for('zhuce') }}" style="background-color: white"><span class="glyphicon glyphicon-user"></span> 注册</a></li> <li><a href="{{ url_for('denglu') }}" style="background-color: white"><span class="glyphicon glyphicon-log-in"></span> 登录</a></li> {% endif %} </ul> </div> </nav>
三、图片导航
可在页面中加入一些图片导航进行美化和补充,可在图片中添加外部链接,中间的图片导航代码如下:
<ul> <div> <div class="img"> <a href="https://baike.baidu.com/item/白羊座/23547?fr=aladdin"> <img src="https://static.meiguoshenpo.com/image/201412/30091426359.png"> </a> <div class="d"><a href="https://baike.baidu.com/item/白羊座/23547?fr=aladdin">白羊座</a></div> </div> <div class="img"> <a href="https://baike.baidu.com/item/金牛座/23548?fr=aladdin"> <img src="https://static.meiguoshenpo.com/image/201412/30091749406.png"> </a> <div class="d"><a href="https://baike.baidu.com/item/金牛座/23548?fr=aladdin">金牛座</a></div> </div> <div class="img"> <a href="https://baike.baidu.com/item/双子座/23549?fr=aladdin"> <img src="http://static.meiguoshenpo.com/image/201411/19135844406.png"> </a> <div class="d"><a href="https://baike.baidu.com/item/双子座/23549?fr=aladdin">双子座</a></div> </div> <div class="img"> <a href="https://baike.baidu.com/item/巨蟹座/2490814?fr=aladdin"> <img src="http://static.meiguoshenpo.com/image/201411/19135552250.png"> </a> <div class="d"><a href="https://baike.baidu.com/item/巨蟹座/2490814?fr=aladdin">巨蟹座</a></div> </div> <div class="img"> <a href="https://baike.baidu.com/item/狮子座/8162?fr=aladdin"> <img src="http://static.meiguoshenpo.com/image/201411/19135128578.png"> </a> <div class="d"><a href="https://baike.baidu.com/item/狮子座/8162?fr=aladdin">狮子座</a></div> </div> <div class="img"> <a href="https://baike.baidu.com/item/室女座/3268873?fr=aladdin&fromid=31025&fromtitle=处女座"> <img src="https://static.meiguoshenpo.com/image/201412/30093428609.png"> </a> <div class="d"><a href="https://baike.baidu.com/item/室女座/3268873?fr=aladdin&fromid=31025&fromtitle=处女座">处女座</a></div> </div> <div class="img"> <a href="https://baike.baidu.com/item/天秤座/2609891"> <img src="https://static.meiguoshenpo.com/image/201412/30093731000.png"> </a> <div class="d"><a href="https://baike.baidu.com/item/天秤座/2609891">天秤座</a></div> </div> <div class="img"> <a href="https://baike.baidu.com/item/天蝎座/2543199"> <img src="http://static.meiguoshenpo.com/image/201412/30094107125.png"> </a> <div class="d"><a href="https://baike.baidu.com/item/天蝎座/2543199">天蝎座</a></div> </div> <div class="img"> <a href="https://baike.baidu.com/item/射手座/126373"> <img src="https://static.meiguoshenpo.com/image/201412/30094719515.png"> </a> <div class="d"><a href="https://baike.baidu.com/item/射手座/126373">射手座</a></div> </div> <div class="img"> <a href="https://baike.baidu.com/item/摩羯座/2546779"> <img src="https://static.meiguoshenpo.com/image/201412/30095016421.png"> </a> <div class="d"><a href="https://baike.baidu.com/item/摩羯座/2546779">摩羯座</a></div> </div> <div class="img"> <a href="https://baike.baidu.com/item/水瓶座/128102"> <img src="https://static.meiguoshenpo.com/image/201412/30095405703.png"> </a> <div class="d"><a href="https://baike.baidu.com/item/水瓶座/128102">水瓶座</a></div> </div> <div class="img"> <a href="https://baike.baidu.com/item/双鱼座/23550"> <img src="https://static.meiguoshenpo.com/image/201412/30095742312.png"> </a> <div class="d"><a href="https://baike.baidu.com/item/双鱼座/23550">双鱼座</a></div> </div> </div> </ul>
四、注册功能:

- js文件: onclick函数return True时才提交表单,return False时不提交表单。
- html文件:
- <form>中设置 action和method="post"
- <input> 中设置 name
- 主py文件中:
- from flask import request, redirect, url_for
- @app.route('/regist/', methods=['GET', 'POST’])
{% extends 'base.html' %} {% block title %} 注册 {% endblock %} {% block main %} <link href="../static/css/hh.css" rel="stylesheet" type="text/css"> <script src="../static/js/zc.js"></script> <div><h1>注册</h1></div><br><br><br> <form action="{{ url_for('zhuce') }}" method="post"> <div class="box"> <p class="input_box"> 账户: <input id="uname" type="text" placeholder="请输入您的昵称" name="username"> </p> <p class="input_box"> 密码: <input id="upass" type="password" placeholder="请设置您的密码" name="password"> </p> <p class="input_box"> 验证: <input id="upass1" type="password" placeholder="请再次输入密码" name="password"> </p> <div id="error_box"><br></div> <div class="input_button"> <button type="submit" onclick="return fozhuce()">立即注册</button> </div> </div> </form> {% endblock %}
function fozhuce() { var oUname = document.getElementById("uname"); var oError = document.getElementById("error_box"); var oUpass = document.getElementById("upass"); var oUpass1 = document.getElementById("upass1"); var isError = true; oError.innerHTML = "<br>"; if (oUname.value.length < 6 || oUname.value.length > 20) { oError.innerHTML = "用户名要6-20位"; isError = false; return isError; }else if(oUname.value.charCodeAt(0)>=48 &&(oUname.value.charCodeAt(0)<=57)){ oError.innerHTML="首位不能为数字"; isError = false; return isError; }else for (var i=0;i<oUname.value.length;i++){ if((oUname.value.charCodeAt(i)<48)||(oUname.value.charCodeAt(i)>57)&&(oUname.value.charCodeAt(i)<58)&&(oUname.value.charCodeAt(i)>97)){ oError.innerHTML="只能为数字和字母"; isError = false; return isError; } }if (oUpass.value.length < 6 || oUpass.value.length > 20) { oError.innerHTML = "密码要6-20位"; isError = false; return isError; }else if(oUpass.value!=oUpass1.value) { oError.innerHTML = "设置密码和验证密码不一致"; isError = false; return isError; } return ture; }
五、登录功能:

{% extends 'base.html' %} {% block title %} 登录 {% endblock %} {% block main %} <link rel="stylesheet" type="text/css" href="../static/css/hh.css"> <script src="../static/js/dl.js"></script> <div><h1>登录</h1></div> <br><br><br> <body><div class="box"> <form action="{{ url_for('denglu') }}" method="post"> <p class="input_box"> 账户: <input id="uname" type="text" placeholder="请输入您的用户名"name="username"> </p> <p class="input_box"> 密码: <input id="upass" type="password" placeholder="请输入您的密码" name="password"> </p> <div id="error_box"><br></div> <div class="input_box"> <button onclick="return fnLogin()">登录</button> </div> </form> {% endblock %} </body>
function foLogin() { var oUname = document.getElementById("uname"); var oError = document.getElementById("error_box"); var oUpass = document.getElementById("upass"); var isError = true; oError.innerHTML = "<br>"; if (oUname.value.length < 6 || oUname.value.length > 12) { oError.innerHTML = "用户名要6-12位"; isError = false; return; }else if(oUname.value.charCodeAt(0)>=48 &&(oUname.value.charCodeAt(0)<=57)){ oError.innerHTML="首位不能为数字"; isError = false; return isError; }else for (var i=0;i<oUname.value.length;i++){ if((oUname.value.charCodeAt(i)<48)||(oUname.value.charCodeAt(i)>57)&&(oUname.value.charCodeAt(i)<58)&&(oUname.value.charCodeAt(i)>97)){ oError.innerHTML="只能为数字和字母"; isError = false; return isError; } } if (oUpass.value.length < 6 || oUpass.value.length > 12) { oError.innerHTML = "密码要6-20位"; isError = false; isError = false; return isError; } return ture; }
py:
1.@app.route设置methods
2.GET
3.POST
1.读取表单数据
2.查询数据库
1.用户名密码对:
1.记住用户名
2.跳转到首页
1.用户名密码不对:
1.提示相应错误。
def zhuce(): if request.method == 'GET': return render_template('zc.html') else: username = request.form.get('username') # 获取form中的数据 password = request.form.get('password') # 获取form中的数据 # email = request.form.get('email') # 获取form中的数据 user = User.query.filter(User.username ==username).first() if user: return'用户已存在' else: user = User(username = username,password=password) db.session.add(user) db.session.commit() return redirect(url_for('denglu')) @app.route('/denglu/', methods=['GET', 'POST']) def denglu(): if request.method == 'GET': return render_template('dl.html') else: username = request.form.get('username') password = request.form.get('password') user = User.query.filter(User.username == username).first() # 判断用户名是否存在 if user: if user.check_password(password): session['user'] = username session['id'] = user.id session.permanent = True return redirect(url_for('shouye')) else: return '密码错误' else: return '此用户不存在'
六、 登录后更新导航:
用上下文处理器app_context_processor定义函数
- 获取session中保存的值
- 返回字典
app = Flask(__name__) app.config.from_object(config) db = SQLAlchemy(app
@app.context_processor def mycontext(): usern=session.get('user') if usern: return {'username':usern} else: return{}
3.完成注销功能。
1.清除session
2.跳转
@app.route('/logout/') def logout(): session.clear(); return redirect(url_for('shouye'))
七、发布功能
1.编写要求登录的装饰器
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.完成发布函数。
保存到数据库。
重定向到首页
八、在首页显示问答列表
1. 在首页添加显示问答的列表,并定义好相应的样式。
无序列表
<ul >
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
2. 用字典向index.html传递参数。
- 首页列表显示全部问答:
- 将数据库查询结果传递到前端页面 Question.query.all()
- 前端页面循环显示整个列表。
- 问答排序
- 完成问答详情页布局:
- 包含问答的全部信息
- 评论区
- 以往评论列表显示区。
- 在首页点击问答标题,链接到相应详情页。
九、从首页问答列表标题链接到问题详情页
- 主PY文件写视图函数,带id参数。
@app.route('/detail/<question_id>')
def detail(question_id):
quest =
return render_template('detail.html', ques = quest) - 首页标题的标签做带参数的链接。
{{ url_for('detail',question_id = foo.id) }} - 在详情页将数据的显示在恰当的位置。
{{ ques.title}}
{{ ques.id }}{{ ques.creat_time }}{{ ques.author.username }}
{{ ques.detail }} -
建立评论的对象关系映射:
class Comment(db.Model):
__tablename__='comment'
十、发布评论
1.定义评论的视图函数
@app.route('/comment/',methods=['POST'])
def comment():
读取前端页面数据,保存到数据库中
@app.route('/comment/', methods=['POST']) @log def comment(): comment=request.form.get('new_comment') ques_id=request.form.get('question_id') auth_id=User.query.filter(User.username==session.get('user')).first().id comm=Comment(author_id=auth_id,question_id=ques_id,detail=comment) db.session.add(comm) db.session.commit() return redirect(url_for('detail',question_id=ques_id))
2.用<input type="hidden" 方法获取前端的"question_id"
3.显示评论次数
4.要求评论前登录
{% extends 'base.html' %} {% block title %} 问答详情 {% endblock %} {% block main %} <link rel="stylesheet" type="text/css" href="../static/css/detail.css"> <div class="box"> <h3 href="#" style="color: black">问题标题:{{ ques.title }}</h3> {% for foo in ques.comments %} <a style="color: black;background-color: beige" href="{{ url_for('usercenter',user_id = foo.author.id,tag='1') }}">发布者: {{ ques.author.username }}<a><span class="badge" style="margin-left: 75%">发布时间{{ ques.create_time }}</span> {% endfor %} <hr> <p style="font-size: 18px;color: black;">问题详情:{{ ques.detail }}</p> <hr> <form action="{{ url_for('comment') }}" method="post"> <div><textarea class="form-control" id="comment" rows="3" style="margin-left: 1%" name="new_comment" placeholder="写下你的评论吧"></textarea><br></div> <input type="hidden" name="question_id" value="{{ ques.id }}"> <button type="submit" style="color: black">发送</button> </form> <h4 style="color: black">评论:({{ ques.comments|length }})</h4> <ul class="list-unstyled"> {% for foo in ques.comments %} <li class="list-group-item"> <a href="{{ url_for('usercenter',user_id = foo.author.id,tag='1') }}">{{ foo.author.username }}</a> <span class="badge pull-right">{{ foo.create_time }}</span> <p>{{ foo.detail }}</p> <br> </li> {% endfor %} </ul> </div> {% endblock %}
十一、个人中心
- 个人中心—视图函数带标签页面参数tag
- @app.route('/usercenter/<user_id>/<tag>')
def usercenter(user_id, tag):
if tag == ‘1':
return render_template('usercenter1.html', **context)
@app.route('/usercenter/<user_id><tag>') @log def usercenter(user_id,tag): user = User.query.filter(User.id == user_id).first() context = { 'user': user, 'questions': user.question, 'comments': user.comments } if tag == '1': return render_template('user1.html', **context) elif tag == '2': return render_template('user2.html', **context) else: return render_template('user3.html', **context)
3.个人中心—导航标签链接增加tag参数
<li role=“presentation”><a href=“{{ url_for(‘usercenter’,user_id = user.id,tag = ‘1’) }}">全部问答</a></li>
<li><a href="{{ url_for('usercenter',user_id=user.id,tag = 1) }}" >全部问答</a></li> <li><a href="{{ url_for('usercenter',user_id=user.id,tag = 2) }}" >全部评论</a></li> <li><a href="{{ url_for('usercenter',user_id=user.id,tag = 3) }}">个人信息</a></li>
4.个人中心—有链接到个人中心页面的url增加tag参数
<a href="{{ url_for('usercenter',user_id = session.get('userid'), tag=1) }}">{{ session.get('user') }}</a>
十二、搜索功能
1.修改base.html 中搜索输入框所在的
- <form action="{{ url_for('search') }}" method="get">
- <input name="q" type="text" placeholder="请输入关键字">
2.完成视图函数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)
@app.route('/search/') def search(): qu = request.args.get('q') ques = Question.query.filter( or_( Question.title.contains(qu), Question.detail.contains(qu) ) ).order_by('') return render_template('hh.html',questions=ques)
十三、密码保护
设置密码保护后,用户注册时输入的密码在存入数据库时转为编译后的密码,在外部从数据库看到的密码是编译后的
1.更新User对象,设置对内的_password
class User(db.Model):
__tablename__ = 'user'
_password = db.Column(db.String(200), nullable=False) #内部使用
class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True, autoincrement=True) username = db.Column(db.String(100), nullable=False) _password = db.Column(db.String(500), 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)
@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
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):
@app.route('/denglu/', methods=['GET', 'POST']) def denglu(): if request.method == 'GET': return render_template('dl.html') else: username = request.form.get('username') password = request.form.get('password') user = User.query.filter(User.username == username).first() # 判断用户名是否存在 if user: if user.check_password(password): session['user'] = username session['id'] = user.id session.permanent = True return redirect(url_for('shouye')) else: return '密码错误' else: return '此用户不存在'
浙公网安备 33010602011771号