个人学期总结
总结了一下这个学期所学的信息管理系统课程,使用Python+Flask+MysqL的web建设
件
完成基本的页面设计
导航条
主界面
登录界面
注册界面
加载静态文件,父模板与其他界面的继承
1.登陆用url_for加载静态文件
1.<script src="{{ url_for('static',filename='js/login.js') }}"></script>
2.flask 从static文件夹开始寻找
3.可用于加载css, js, image文件
2.继承和扩展
1.把一些公共的代码放在父模板中,避免每个模板写同样的内容。base.html
2.子模板继承父模板
1.{% extends 'base.html’ %}
3.父模板提前定义好子模板可以实现一些自己需求的位置及名称。block
1.<title>{% block title %}{% endblock %}-MIS问答平台</title>
2.{% block head %}{% endblock %}
3.{% block main %}{% endblock %}
4.子模板中写代码实现自己的需求。block
1.{% block title %}登录{% endblock %}
数据库的建表与连接
db=SQLAlchemy(app)
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) #内部使用
@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)
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('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'))
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()
注册功能的实现
- 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’])
@app.route('/sign_up/',methods=['GET','POST']) def sign_up(): 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 'username existed.' else: user1 = User(username=username, password=password) db.session.add(user1) db.session.commit() return redirect(url_for('sign_in'))
登录功能的实现
function MyLogin() { var oUname=document.getElementById("uname"); var oUpass=document.getElementById("upass"); var oError=document.getElementById("errorbox"); //username if(oUname.value=="Username"&&oUpass.value=="Password"){ oError.innerHTML="请输入账号"; return false; }else if(oUname.value.length<6||oUname.value.length>12){ oError.innerHTML="账号必须为6至12位"; return false; }else if(oUname.value.charCodeAt(0)>=48 && oUname.value.charCodeAt(0)<=57){ oError.innerHTML="首位为字母"; return false; }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) < 97 || oUname.value.charCodeAt(i) > 122)) { oError.innerHTML = "只有数字或字母"; return false; } } //password if(oUpass.value.length<6||oUpass.value.length>12) { oError.innerHTML = "密码必须为6至12位"; return false; } return true; // window.alert("Login Successful") }
实现登录后更新导航:用上下文处理器app_context_processor定义函数,获取session中保存的值,返回字典。在父模板中更新导航,插入登录状态判断代码。注意用{% ... %}表示指令、{{ }}表示变量。完成注销功能:清除session并进行跳转页面。
@app.context_processor
def mycontext():
usern=session.get('user')
if usern:
return {'username':usern}
else:
return {}
@app.route('/logout/')
def logout():
session.clear()
return redirect(url_for('home'))
编写要求登录的装饰器,定义函数将其返回。应用装饰器,要求在发布前进行登录,登录后可发布。建立发布内容的对象关系映射,完成发布函数。
@app.route('/question/',methods=['GET','POST'])
@loginFrist
def question():
if request.method == 'GET':
return render_template('question.html')
else:
title = request.form.get('title')
detail = request.form.get('detail')
user=User.query.filter(User.username == session.get('user')).first()
author_id = user.id
question = Question.query.filter(Question.title == title).first()
if question:
return 'Question existed'
else:
question1 = Question(title=title, detail=detail, author_id=author_id)
question1.author = user
db.session.add(question1) # 保存到数据库
db.session.commit() # 提交
return redirect(url_for('home'))
def loginFrist(func):
@wraps(func)
def wrapper(*args,**kwargs):
if session.get('user'):
return func(*args,**kwargs)
else:
return redirect(url_for('login'))
return wrapper
问答的发布
主PY文件写视图函数,带id参数。 首页标题的标签做带参数的链接,在详情页将数据的显示在恰当的位置。建立评论的对象关系映射,尝试实现发布评论。
完成评论功能:定义评论的视图函数,读取前端页面数据,保存到数据库中。用<input type="hidden" 方法获取前端的"question_id" ,显示评论次数,要求评论前登录(调用登录装饰器),尝试实现详情页面下的评论列表显示。
@app.route('/comment/',methods=['POST'])
@loginFirst
def comment():
detail=request.form.get('detail')
author_id = User.query.filter(User.username == session.get('user')).first().id
question_id = request.form.get('question_id')
comment = Comment(author_id=author_id,question_id=question_id,detail=detail)
db.session.add(comment) # 保存到数据库
db.session.commit() # 提交
return redirect(url_for('detail',question_id=question_id))
如此则完成了一集齐登录、注册、发布问答简单功能的web项目系统。