1.期末作品检查:基本要求
(1)检查时间:18最后四节课,上课之前必须全部完成,上课做基本部署就开始检查
(2)方式:逐个运行演示,抽查代码
(3)主题:选一个主题,整个网站风格统一,布局合理,尽量美观。
2.期末作品检查:必须完成:
(1)网站父模板统一布局:头部导航条、底部图片导航、中间主显示区域布局
(2)注册、登录、注销
(3)发布、列表显示
(4)详情页
(5)评论、列表显示
(6)个人中心
3.搜索,条件组合搜索一篇完整的博客
- 个人学期总结,总结Python+Flask+Mysql的web建设技术过程,标准如下: (1)即是对自己所学知识的梳理
- (2)也可作为初学入门者的简单教程
- (3)也可作为自己以后复习的向导
- (4)也是一种向外展示能力的途径
- 4.期末作品检查:加分功能
- (1)文章分类、显示
- (2)点赞、收藏
- (3)修改密码、头像、上传头像
- (4)我的
- (5)高级搜索
一、个人学期总结俗话说:活到老学到老,我们要继续努力,抓紧自己的学习。知识无止境,探索无止境,人的发展亦无止境。在今后的日子里,我仍然要不断地充实自己,争取在所学领域有所作为。 脚踏实地,认真严谨,实事求是的学习态度,
一学期匆匆过去,从一个菜鸟到可以初步做一个简单的网页系统,这不仅是进步,更是挑战。 回想刚开始学这门课程,那个时候,还不了解Python语言是什么。在老师的教授下,从最开始的基础练习—用Python语言画简单的图案,慢慢地到制作web页面。
真的感概一步一个脚印,慢慢积累知识的重要性。
二、作品展示——维尼熊主题
(一)前期准备
1.连接数据库
import os SQLALCHEMY_DATABASE_URI = ‘mysql+pymysql://root:@127.0.0.1:3306/mis15?charset=utf8‘ SQLALCHEMY_TRACK_MODIFICATIONS = False SECRET_KEY =os.urandom(24)
2.创建表储存数据
class User(db.Model): __tablename__ = ‘User‘ id = db.Column(db.Integer,primary_key=True,autoincrement=True) username = db.Column(db.String(20),nullable=False) _password = db.Column(db.String(200), nullable=False)#内部使用 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) 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(‘questions‘)) 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‘)) detail=db.Column(db.Text,nullable=False) creat_time = db.Column(db.DateTime, default=datetime.now) question = db.relationship(‘Question‘, backref=db.backref(‘comments‘,order_by=creat_time.desc)) author = db.relationship(‘User‘, backref=db.backref(‘comments‘)) db.create_all()
3.定义函数
@app.route(‘/‘)#添加装饰器 def base(): return render_template("base.html") @app.context_processor def mycontext(): username=session.get(‘user‘) if username: return {‘username‘:username} else: return{} @app.route(‘/logout‘) def logout(): session.clear() return redirect(url_for(‘base‘)) @app.route(‘/denglu/‘, methods=[‘GET‘, ‘POST‘]) def denglu(): if request.method == ‘GET‘: return render_template("denglu.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[‘userid‘]=user.id session.permanent = True return redirect(url_for(‘index‘)) else: return ‘密码错误‘ else: return ‘用户名不存在‘ @app.route(‘/zhuce/‘, methods=[‘GET‘, ‘POST‘]) def zhuce(): if request.method == ‘GET‘: return render_template("zhuce.html") else: username = request.form.get(‘username‘) password = request.form.get(‘password‘) 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‘)) def log(func): @wraps(func) def wrapper(*args,**kwargs): if session.get(‘user‘): return func(*args,**kwargs) else: return redirect(url_for(‘denglu‘)) return wrapper @app.route(‘/question/‘,methods=[‘GET‘,‘POST‘]) @log 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 user = User.query.filter(User.username == session.get(‘user‘)).first() question=Question(title=title,detail=detail,author_id=author_id) question.author = user db.session.add(question)#保存到数据库 db.session.commit()#提交 return redirect(url_for(‘index‘)) @app.route(‘/index‘) def index(): context={ ‘questions‘: Question.query.all(), } return render_template(‘index.html‘,**context) @app.route(‘/detail/<question_id>‘) @log def detail(question_id): quest=Question.query.filter(Question.id==question_id).first() return render_template("detail.html",ques=quest) return question_id @app.route(‘/comment/‘,methods=[‘GET‘,‘POST‘]) @log def comment(): if request.method == ‘GET‘: return render_template("detail.html") else: comment = request.form.get(‘new_comment‘) ques_id = request.form.get(‘question_id‘) author_id = User.query.filter(User.username == session.get(‘user‘)).first().id comm = Comment(author_id=author_id,question_id=ques_id,detail=comment) db.session.add(comm) # 保存到数据库 db.session.commit() # 提交 return redirect(url_for(‘detail‘,question_id =ques_id)) @app.route(‘/usercenter/<user_id>/<tag>‘) @log def usercenter(user_id,tag): user=User.query.filter(User.id==user_id).first() context={ ‘username1‘:user.username, ‘questions‘:user.questions, ‘comments‘:user.comments, ‘id‘:user.id } if tag == ‘1‘: return render_template(‘usercenter.html‘, **context) elif tag == ‘2‘: return render_template(‘user1.html‘, **context) else: return render_template(‘user2.html‘,**context) @app.route(‘/search/‘) def search(): qu=request.args.get(‘q‘) ques=Question.query.filter( or_( Question.title.contains(qu), Question.detail.contains(qu), ) ) return render_template(‘index.html‘,questions=ques)
(二)代码及展示
1.进入网站——父模板
主要代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %} {% endblock %}维尼乐园</title> <link rel="stylesheet" type="text/css" href="{{ url_for(‘static‘,filename=‘css/20.css‘) }}"> <script src="{{ url_for(‘static‘,filename=‘js/on_off.js‘) }}"></script> </head> {% block head %} {% endblock %} <body id="mybody" background="../static/images/background.jpg" style="width:100%;height: 100%;" > <header class="navbar-wrapper"> <div class="navbar navbar-black"> <div class="container cl"> <form action="{{ url_for(‘search‘) }}" method="get" style="text-align: center;float: right;"> <input name="q" type="text" placeholder="搜索从这里开始..." style="width: 180px;padding-left:14px;height: 28px;border: 2px solid #7BA7AB;border-radius: 5px;outline: none;background: #F9F0DA;color: #9E9C9C;"> <button type="submit" style="width: 55px;height: 31px;border: none;background: #7BA7AB;border-radius: 0 5px 5px 0;cursor: pointer;">查找</button> </form> <nav class="nav navbar-nav nav-collapse" role="navigation" id="Hui-navbar"> <ul class="cl"> <li><a class="logo navbar-logo f-l mr-10 hidden-xs" href="{{ url_for(‘index‘) }}" style="color: royalblue;text-decoration:none;">首页</a></li> <li><span class="logo navbar-slogan f-l mr-10 hidden-xs">简单 · 快乐 · 维尼世界</span></li> {% if username %} <li><a href="{{ url_for(‘usercenter‘,user_id=session.get(‘userid‘),tag=1) }}" style="color: royalblue;text-decoration:none;">{{ username }}</a></li> <li><a href="{{ url_for(‘logout‘) }}"style="color: royalblue;text-decoration:none;">注销</a></li> {% else %} <li><a href="{{ url_for(‘denglu‘)}}"style="color: royalblue;text-decoration:none;">登录</a></li> <li><a href="{{ url_for(‘zhuce‘) }}"style="color: royalblue;text-decoration:none;">注册</a></li> {% endif %} <li><a href="{{ url_for(‘question‘) }}"style="color: royalblue;text-decoration:none;">发布问答</a></li> </ul> </nav> </div> {% block main %} <div class="container-fluid"> <img src="../static/images/5.png" style="width: 620px;height: 500px;position:absolute;right:0px;top:50px;" > <img src="../static/images/3.png" style="width: 320px;height: 250px;position:absolute;left:0px;top:350px;" > </div> <footer class="footer mt-20" > <div class="weini" > <img src="../static/images/41.jpg" style="width: 100px;height: 100px;top: 100px;" > <img src="../static/images/10.jpg" style="width: 100px;height: 100px;top: 100px;" > <img src="../static/images/14.jpg" style="width: 100px;height: 100px;top: 100px;" > <img src="../static/images/55.jpg" style="width: 100px;height: 100px;top: 100px;" > <img src="../static/images/66.jpg" style="width: 100px;height: 100px;top: 100px;" > <nav> <a href="https://book.douban.com/subject/10773252/" target="_blank">维尼的烦恼</a> <span class="pipe"><img src="../static/images/111.png" style="width: 30px;height: 30px;" ></span> <a href="http://www.4399er.com/xzt/gszt/xxwnsqgs/" target="_blank">小猪的笑容</a> <span class="pipe"><img src="../static/images/111.png" style="width: 30px;height: 30px;" ></span> <a href="http://dy.163.com/v2/article/detail/CCT2TF3R05298ID3.html" target="_blank">快乐的维尼</a> <span class="pipe"><img src="../static/images/111.png" style="width: 30px;height: 30px;" ></span> <a href="http://www.iqiyi.com/a_19rrjul0zx.html" target="_blank">维尼的日常</a> <span class="pipe"><img src="../static/images/111.png" style="width: 30px;height: 30px;" ></span> <a href="http://www.baike.com/wiki/%E7%BB%B4%E5%B0%BC%E7%86%8A" target="_blank">小猪的幼稚</a> </nav> </div> </footer> </div> </div> </header> </body> </html> {% endblock %}
2.注册
主要代码:
{% extends ‘base.html‘ %} {% block title %} 注册 {% endblock %} {% block head %} <link rel="stylesheet" type="text/css" href="{{ url_for(‘static‘,filename=‘css/denglu.css‘) }}"> <script src="../static/js/zhuce.js"></script> {% endblock %} {% block main %} <body> <img src="../static/images/3.png" style="width: 320px;height: 250px;position:absolute;left:0px;top:350px;" > <img src="../static/images/5.png" style="width: 620px;height: 500px;position:absolute;right:0px;top:250px;" > <div class="box"> <div class="titulo">Regist</div> <form class="form" method="post" action="{{ url_for(‘zhuce‘) }}"> <div class="input_box1" > <input id="uname" name="username" type="text" placeholder="请输入用户名" > </div> <div class="input_box2"> <input id="upass" name="password" type="password" placeholder="请输入密码"> </div> <div class="input_box2"> <input id="upass1" name="password" type="password" placeholder="请确认密码" > </div> <div id="error_box"><br></div> <div class="input_box3" > <button onclick="return myLogin()"><img src="../static/images/call.png" style="width: 30px;height: 30px"></button> </div> </form> </div> </body> {% endblock %}
3.登录
主要代码:
{% extends ‘base.html‘ %} {% block title %} 登录 {% endblock %} {% block head %} <link href="../static/css/denglu.css" rel="stylesheet" type="text/css"> <script src="../static/js/zhuce.js"></script> {% endblock %} {% block main %} <body> <img src="../static/images/3.png" style="width: 320px;height: 250px;position:absolute;left:0px;top:350px;" > <img src="../static/images/5.png" style="width: 620px;height: 500px;position:absolute;right:0px;top:250px;" > <div class="box"> <div class="titulo">Login</div> <form action="{{ url_for(‘denglu‘) }}" method="post"></form> <form class="form" method="post" action="{{ url_for(‘denglu‘) }}"> <div class="input_box1" > <input id="uname" name="username" type="text" placeholder="请输入用户名"> </div> <div class="input_box2"> <input id="upass" name="password" type="password" placeholder="请输入密码"> </div> <div id="error_box"><br></div> <div class="input_box3"> <button onclick="return myLogin()"><img src="../static/images/call.png" style="width: 30px;height: 30px"></button> </div> </form> </div> </body> {% endblock %}
检测注册、登录:
function myLogin() { var oUname = document.getElementById("uname"); var oUpass = document.getElementById("upass"); var oUpass1 = document.getElementById("upass1"); var oError = document.getElementById("error_box"); oError.innerHTML = "<br>" if (oUname.value.length < 2 || oUname.value.length > 12) { oError.innerHTML = "用户名必须大于2位或少于12位!"; return false; } else if((oUname.value.charCodeAt(0)>=48)&&(oUname.value.charCodeAt(0)<=57)){ oError.innerHTML="首字母不能是数字!"; return false; } if (oUpass.value.length < 6 || oUpass.value.length > 12) { oError.innerHTML = "密码必须大于6位或少于12位!"; isError=false; return isError; } else if (oUpass.value!=oUpass1.value){ oError.innerHTML="两次密码不一样"; isError=false; return isError; } return true; window.alert("注册成功!") }
4.首页
主要代码:
{% extends ‘base.html‘ %} {% block title %} 首页 {% endblock %} {% block head %} <link type="text/css" rel="stylesheet" href="{{ url_for(‘static‘,filename=‘css/index.css‘) }}"> {% endblock %} {% block main %} <body> <img src="../static/images/3.png" style="width: 320px;height: 250px;position:absolute;left:0px;top:350px;" > <img src="../static/images/9.png" width="520" height="400" style="position:absolute;left:950px;top:350px;"> <ul class="list1" > <img src="../static/images/myself.jpg" width="60" height="60"> {% for foo in questions %} <li class="list-group-item"> <span class="glyphicon glyphicon-leaf" aria-hidden="true"></span> {% if username %} <li class="zero"><a href="{{ url_for(‘detail‘,question_id=foo.id) }}">{{ foo.title }}</a></li> {% endif %} <a class="#"></a> <br> <span class="badge">{{ foo.creat_time }}</span> <li class="one" ><a href="{{ url_for(‘usercenter‘,user_id=foo.author_id,tag=1) }}">{{ foo.author.username }}</a></li> <li class="two"><p style="text-indent: 18px">{{ foo.detail }}</p></li> </li> {% endfor %} </ul> </body> {% endblock %}
3.发布问答
主要代码:
{% extends ‘base.html‘ %} {% block title %} 问答 {% endblock %} {% block head %} <meta charset="UTF-8"> <link type="text/css" rel="stylesheet" href="../static/css/question.css"> {% endblock %} {% block main %} <body> <img src="../static/images/3.png" style="width: 320px;height: 250px;position:absolute;left:0px;top:350px;" > <img src="../static/images/8.png" style="position:absolute;right:150px;top:50px;;width: 400px;height: 300px;"> <div class="label"> <h1 style="color:lightseagreen",align="center">发布问答</h1> <form action="{{ url_for(‘question‘) }}" method="post"> <div class="q" style="font-family: inherit"> <label for="question">问题</label> <textarea name="title" textarea id="question" cols="50" rows="1"></textarea> </div> <div class="form-group"> <label for="questionDetail">详情</label> <textarea name="detail" textarea class="form-control" id="questionDetail" cols="50" rows="5"></textarea> </div> <div class="input-area"> <button type="submit" class="btn btn-default"><img src="../static/images/egg.png" style="width: 30px;height: 30px"></button> </div> </form> </div> </body> {% endblock %}
4.问答详情页
主要代码:
{% extends ‘base.html‘ %} {% block title %} 问答详情页 {% endblock %} {% block head %} <link type="text/css" rel="stylesheet" href="../static/css/detail.css"> {% endblock %} {% block main %} <body> <img src="../static/images/3.png" style="width: 320px;height: 250px;position:absolute;left:0px;top:350px;" > <img src="../static/images/6.png" style="position:absolute;right:0px;top:400px;;width: 400px;height: 350px;"> <ul class="list"> <div class="page-header"> <h3><img src="../static/images/66.jpg" style="width: 60px;height: 60px;">{{ ques.title }}<br></h3> <a href="{{ url_for(‘usercenter‘,user_id=ques.author_id,tag=1) }}">{{ ques.author.username }}</a> </div> <p class="answer" style="text-indent: 18px">{{ ques.detail }}</p><hr> <form action="{{ url_for(‘comment‘) }}" method="post"> <span class="badge">{{ ques.creat_time }}</span> <div> <textarea name="new_comment" class="form-control" rows="3" id="new-comment" placeholder="我也说一句..." style="width: 700px;"></textarea> <input name="question_id" type="hidden" value="{{ ques.id }}" > </div> <button type="submit" class="btn btn-default">发送</button> </form><hr> <div class="pinglunqu"> <h4>?评论:({{ ques.comments|length }})</h4><br> <ul class="list1"> {% for ques in ques.comments %} <img style="width: 30px" src="{{ url_for(‘static‘,filename=‘../static/images/friends.jpg‘) }}" > <a href="{{ url_for(‘usercenter‘,user_id=ques.author_id,tag=1) }}">{{ ques.author.username }}</a> <span class="badge">{{ ques.creat_time }}</span><br> <p class="pinglun">评论:{{ ques.detail }}</p> {% endfor %} </ul> </div> </ul> </body> {% endblock %}
5.个人中心-全部问答
主要代码:
{% extends ‘base.html‘ %} {% block title %} 个人中心-问答 {% endblock %} {% block head %} <link type="text/css" rel="stylesheet" href="{{ url_for(‘static‘,filename=‘css/usercenter.css‘) }}"> {% endblock %} {% block main %} <div class="page-header"> <ul class="nav_ul"> <li class="one"><a href="{{ url_for(‘usercenter‘,user_id=id,tag=‘1‘) }}">全部问答</a></li> <li class="one"><a href="{{ url_for(‘usercenter‘,user_id=id,tag=‘2‘) }}">全部评论</a></li> <li class="one"><a href="{{ url_for(‘usercenter‘,user_id=id,tag=‘3‘) }}">个人资料</a></li> </ul> {% block user %}{% endblock %} <div class="list-group" style="align-items: center"> {% for foo in questions %} <li class="list-group-item"> <span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span> <a href="{{ url_for(‘usercenter‘,user_id=foo.author_id,tag=1)}}">{{ foo.author.username }}</a> <span class="badge">{{ foo.creat_time }}</span> <p style="text-indent: 18px">{{ foo.title }}</p> </li> {% endfor %} </div> </div> {% endblock %}
6.个人中心-全部评论
主要代码:
{% extends ‘usercenter.html‘ %} {% block head %} <link href="{{ url_for(‘static‘,filename=‘css/usercenter.css‘) }}" rel="stylesheet" type="text/css" > {% endblock %} {% block user %} <div class="list"> <ul class="list-group"style="margin:10px"> {% for ques in questions %} <li class="list-group-item"> <span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span> <a href="#">{{ ques.author.username }}</a> <span class="badge">{{ ques.creat_time }}</span> <p style="align-content: center">{{ ques.detail }}</p> </li> {% endfor %} </ul> </div> {% endblock %}
7.个人中心-个人信息
主要代码:
{% extends ‘usercenter.html‘ %} {% block head %} <link href="{{ url_for(‘static‘,filename=‘css/usercenter.css‘) }}" rel="stylesheet" type="text/css" > {% endblock %} {% block user %} <ul class="list-group" style="align-items: center"> <li class="list-group-item">用户:{{ username1 }}</li> <li class="list-group-item">编号:{{ id }}</li> <li class="list-group-item">评论数:{{ comments|length }}</li> <li class="list-group-item">文章篇数:{{ questions|length }}</li> </ul> {% endblock %}
(三)细节处理
1,搜索框
from werkzeug.security import generate_password_hash,check_password_hash
@app.route(‘/search/‘)
def search():
qu=request.args.get(‘q‘)
ques=Question.query.filter(
or_(
Question.title.contains(qu),
Question.detail.contains(qu),
)
)
return render_template(‘index.html‘,questions=ques)
2.密码保护
@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
3.注销
@app.route(‘/logout‘) def logout(): session.clear() return redirect(url_for(‘base‘))
三、结束语
以上便是我这个学期在Python+Flask+MysqL的web建设技术过程学习内容的总结和梳理,虽然是刚刚入门,还是新手,但是也了解到这方面许多需求和知识。如有疏漏请谅解,我会继续努力,
在这方面加强学习,希望可以学得更好。