1、个人学习心得
这学期是是第一次接触python,我们首先学的是简单的输出输入计算,到引入 turtle库,绘制多种多样的图形,接着学习了字符串基本操作,进行了中英文词频统计,直到最后我们学习了Python+Flask+MysqL的web建设,做出了自己的网页。我们由浅入深,一步一步的学习python语言,在一些小细节上有遇到过很多问题,但也在努力的解决各种问题。认识web,认识了URL是Uniform Resource Locator的简写,统一资源定位符。一个URL由以下几部分组成:scheme://host:port/path/?query-string=xxx#anchor11;scheme:代表的是访问的协议,一般为http或者https以及ftp等。host:主机名,域名,比如www.baidu.com。port:端口号。浏览器默认http使用80端口,https使用443端口。path:查找路径。如:www.jianshu.com/trending/now,后面的trending/now就是path。query-string:查询字符串,比如:www.baidu.com/s?wd=python,后面的wd=python就是查询字符串。anchor:锚点,后台一般不用管,前端用来做页面定位的。注意:URL中的所有字符都是ASCII字符集,如果出现非ASCII字符,比如中文,浏览器会进行编码再进行传输。认识了html、js、css等,我写了一个包含了导肮页面、登录注册页面、发布问答页面,在后端建设过程中我们引入了flask库中的Flask, render_template,用于创建一个Flask对象以及页面的跳转,引入flask_sqlalchemy库进行数据库的关联映射等,在后端设计过程我们学了对数据的增删改查等操作,利用对数据库的查询添加功能实现了页面的登陆、注册以及发布功能的项目。在css中能定义自己满意的风格样式,在这期间其实会遇到许多问题,总会因为一小点的地方就会出现整个项目不能进行下去,这期间我的状态就是不断的遇到错误也不断的找到错误改掉错误不断的学习。所以这也使我学习了更多的不同的知识,也会认识到很多的错误。收获的是很大的。
2、
期末作品检查:必须完成:
- 网站父模板统一布局:头部导航条、底部图片导航、中间主显示区域布局
- 注册、登录、注销
- 发布、列表显示
- 详情页
- 评论、列表显示
- 个人中心
- 搜索,条件组合搜索
- 一篇完整的博客
- 个人学期总结
- 总结Python+Flask+MysqL的web建设技术过程,标准如下:
- 即是对自己所学知识的梳理
- 也可作为初学入门者的简单教程
- 也可作为自己以后复习的向导
- 也是一种向外展示能力的途径
父模板的图片
注册的部分代码及图片
html:
{% extends 'base.html' %} {% block title %}注册{% endblock %} {% block head %} <link href="../static/css/zhuce.css" rel="stylesheet" type="text/css"> <script src="../static/js/zhuce.js">script> {% endblock %} {% block body %} <div class="container"> <div class="row clearfix"> <div class="col-md-3 column"> div> <div class="col-md-6 column"> <form class="form-horizontal" role="form" action="{{ url_for('zhuce')}}"method="post"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">帐号:label> <div class="col-sm-10"> <input type="text" class="form-control" id="username" name="username" /> div> div> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">昵称:label> <div class="col-sm-10"> <input type="text" class="form-control" id="nickname" name="nickname" /> div> div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">密码:label> <div class="col-sm-10"> <input type="password" class="form-control" id="password" name="password" /> div> div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">确认密码:label> <div class="col-sm-10"> <input type="password" class="form-control" id="inputPassword3" /> div> div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">注册button> div> div> form> div> <div class="col-md-3 column"> div> div> div> {% endblock %}
css
h1{
margin: auto;
width: 50%;
font-weight: bold;
font-size: 20px;
font-family: "宋体";
color: purple;
padding-top: 0;}
.box{
margin: auto;
width: 50%;
font-family: "宋体";
color:deeppink;
}
.input-area{
margin: auto;
width: 50%;
font-family: "宋体";
}
js
function fnLogin() { var oUname = document.getElementById("uname"); var oError = document.getElementById("error_box"); var oUiphone = document.getElementById("uiphone"); var oUpass = document.getElementById("upass"); var oUpass1 = document.getElementById("upass1"); oError.innerHTML="<br>" if(oUname.value.length<6 || oUname.value.length >20){ oError.innerHTML="用户名6-20"; return; }else if ((oUname.value.charCodeAt(0)>=48) && (oUname.value.charCodeAt(0)<=57)){ oError.innerHTML="first number"; return; } else for (var i=0 ; i>57)&&(oUname.value.charCodeAt(i)<97)|| oUname.value.charCodeAt(i)>122){ oError.innerHTML="only letter or number"; return; } } if(oUpass.value.length<6 || oUpass.value.length>20){ oError.innerHTML="密码6-20位"; return; } if (oUpass1.value!=oUpass.value ) { oError.innerHTML = "rewrite your PIN"; return; } window.alert("注册成功") }
登陆的部分代码及截图
html:
{% extends 'base.html' %} {% block title %}登录{% endblock %} {% block head %} <link href="../static/css/denglu.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="../static/js/denglu.js">script> {% endblock %} {% block body %} <div class="container"> <div class="row clearfix"> <div class="col-md-3 column"> div> <div class="col-md-6 column"> <form class="form-horizontal" role="form" action="{{ url_for('denglu')}}"method="post"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">帐号:label> <div class="col-sm-10"> <input type="text" class="form-control" id="username" name="username" /> div> div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">密码:label> <div class="col-sm-10"> <input type="password" class="form-control" id="password" name="pass" /> div> div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <div class="checkbox"> <label><input type="checkbox" />Remember melabel> div> div> div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default" onclick=" return login()">登录button> div> div> <div align="center"> <div id="error_box">div><br> div> form> div> <div class="col-md-3 column"> div> div> div> {% endblock %}
js
function myLogin() { var oUname = document.getElementById("uname"); var oError = document.getElementById("error_box"); var oUpass=document.getElementById("upass"); oError.innerHTML="<br>"; //uname if (oUname.value.length<6 || oUname.value.length>20){ oError.innerHTML="用户名6-20位"; return; }else if((oUname.value.charCodeAt(0)>48) && (oUname.value.charCodeAt(0)<=57)){ oError.innerHTML = "first number"; return; }else for(var i=0;iif (oUname.value.charCodeAt(i)<48 || (oUname.value.charCodeAt(i)>57)&&(oUname.value.charCodeAt(i)<97)|| oUname.value.charCodeAt(i)>122) { oError.innerHTML = "only letter or number"; return; } } //upass if(oUpass.value.length<6||oUpass.value.length>20){ oError.innerHTML="密码6-20位" return; } if((oUname.value.length<6||oUname.value.length>20)&&(oUpass.value.length<6||oUpass.value.length>20)){ oError.innerHTML="用户名密码要求6-20位" return; } window.alert("登陆成功!") }
3.发布问答界面
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.完成发布函数。
保存到数据库。
重定向到首页
@app.route('/question',methods=['GET','POST'])
@loginFirst
def question():
if request.method == 'GET':
return render_template('question.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 = Ques(title=title, detail=detail, author_id=author_id)
db.session.add(question)
db.session.commit()
return redirect(url_for('index'))
4.发布评论
1.定义评论的视图函数 @app.route('/comment/',methods=['POST']) def comment(): 读取前端页面数据,保存到数据库中
@app.route('/comment',methods=['GET','POST'])
@loginFirst
def comment():
comment = request.form.get('detail')
auth_id = User.query.filter(User.username == session.get('user')).first().id # 判断用户名是否存在
question_id = Ques.query.filter(User.username == session.get('user')).first().id
comm = Comment(author_id=auth_id, question_id=question_id, detail=comment)
db.session.add(comm)
db.session.commit()
return redirect(url_for('detail',question_id=question_id))
2.用
3.显示评论次数
4.要求评论前登录
{% extends 'base.html' %} {% block title %}发布问答{% endblock %} {% block head %}{% endblock %} {% block body %} <div class="container"> <div class="row clearfix"> <div class="col-md-3 column"> div> <div class="col-md-6 column"> <form role="form" action="{{ url_for('question')}}"method="post"> <div class="form-group"> <label for="exampleInputEmail1">标题label><input type="text" class="form-control" id="title" name="title"/> div> <div class="form-group"> <label for="exampleInputPassword1">内容label><textarea type="text" class="form-control" id="detail" name="detail" cols="50" rows="10"/>textarea> div> <div class="checkbox"> <label><input type="checkbox"/>Check me outlabel> div> <button type="submit" class="btn btn-default">Submitbutton> form> div> <div class="col-md-3 column"> div> div> div> {% endblock %}
5.首页
1. 在首页添加显示问答的列表,并定义好相应的样式。
无序列表
- Coffee
- Tea
- Milk
2. 用字典向index.html传递参数。
- 首页列表显示全部问答:
- 将数据库查询结果传递到前端页面 Question.query.all()
- 前端页面循环显示整个列表。
- 问答排序
- 完成问答详情页布局:
- 包含问答的全部信息
- 评论区
- 以往评论列表显示区。
- 在首页点击问答标题,链接到相应详情页。
- 主PY文件写视图函数,带id参数。
@app.route('/detail/
') 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'
{% extends 'base.html' %} {% block title %}首页{% endblock %} {% block head %} {% endblock %} {% block body %} <div class="container"> <div class="row clearfix"> <div class="col-md-4 column"> div> <div class="col-md-4 column"> {% for foo in question %} <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title"> <a href="{{ url_for('detail',question_id=foo.id)}}">标题:{{foo.title }}a> <a href="{{ url_for('usercenter',user_id=foo.author.id,tag='1') }}">作者:{{ foo.author.nickname }}a> h3> div> <div class="panel-body"> 内容:{{foo.detail }} div> <div class="panel-footer"> 时间:{{ foo.create_time }} div> {% endfor %} div> <div class="col-md-4 column"> div> div> div> div> {% endblock %}
@app.route('/detail/<question_id>',methods=['GET','POST']) def detail(question_id): quest = Ques.query.filter(Ques.id == question_id).first() comments= Comment.query.filter(Comment.question_id == question_id).all() return render_template('detail.html',quest=quest,comments=comments)
6.个人中心
- 个人中心—视图函数带标签页面参数tag
- @app.route('/usercenter/
/ ') def usercenter(user_id, tag): if tag == ‘1': return render_template('usercenter1.html', **context)
@app.route('/usercenter/<user_id>/<tag>',methods=['GET','POST']) @loginFirst def usercenter(user_id,tag): user = User.query.filter(User.id == user_id).first() context = { 'username_id': user.id, 'username': user.username, 'questions': user.question, 'comments': user.comment } 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 = username_id,tag='1') }}">全部问答a> li> <li role="presentation"> <a href="{{ url_for('usercenter',user_id = username_id,tag='2') }}">全部评论a> li> <li role="presentation"> <a href="{{ url_for('usercenter',user_id = username_id,tag='3')}}" >个人中心a> li>
7.实现导航条中的搜索功能
1.修改base.html 中搜索输入框所在的
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/',methods=['GET','POST'])
def search():
search = request.args.get('search')
question = Ques.query.filter(
or_(
Ques.title.contains(search),
Ques.detail.contains(search)
)
).order_by('-create_time')
return render_template('index.html',question=question)