期末作品检查
这学期的管理信息系统是由杜云梅老师所教,受益匪浅。主要是学习了Python+mysql的web建设技术课程。
前期,老师进行了理论授课,让我们了解并理解管理信息,了解python语句的使用。让我们在博客园这个平台发布我们平时的练习,让我们可以去反复复习,有什么忘了的地方也可以去博客园看。
中期,开始学习用html元素制作web网页,观察常用网页的HTML元素,在实际的应用场景中,用已学的标签模仿制作。制作自己的导航条,认识css的盒子模型,用div等元素布局形成html文件。完成了登录与注册页面的html+css+js, 夜间模式的开启和关闭,制作网站网页共有元素的父模板html,包括顶部导航,中间区块划分,底部导航,底部说明等。汇总相关的样式形成独立的css文件,使用 js代码形成独立的js文件,形成完整的base.html+css+js。
后期,进行flask项目,理解flask项目主程序,使用装饰器,设置路径与函数之间的关系。加载静态文件,父模板的继承和扩展。连接mysql数据库,创建用户模型,通过用户模型,对数据库进行增删改查,完成登录、注册、发布评论等功能,继续对我们的项目进行完善。
二、总结Python+Flask+MysqL的web建设技术过程
Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。Python语言简洁易读以及可扩展可嵌入,已经成为最受欢迎的程序设计语言之一。它简单易学,速度快,免费开源,可移植。
Python拥有一个强大的标准库。Python语言的核心只包含数字、字符串、列表、字典、文件等常见类型和函数。
刚开始学习python的时候,觉得它所使用的代码确实是很简洁易懂,而且非常重视代码的规范性,这种强制性的缩进使得代码更具有可读性,但同时还是给很多初学者包括我带来了困惑。最常见的情况是tab和空格的混用会导致错误,而这是用肉眼无法分别的。所以经常以为是语法错误而在找了很久的错误时才发现只是一个缩进错了。
对于python各种库的使用,我们还是很不熟悉的,目前大多数都是老师介绍的,如果我们要深入对python语言进行研究,各种库的了解也是必不可少的。对于代码的练习更是必不可少,其实任何代码都一样,都需要大量的练习熟悉,锻炼我们的逻辑思维,不可能一蹴而就。
Flask是一个年轻充满活力的微框架,有着众多的拥护者,文档齐全,社区活跃度高。flask处理一个请求的流程就是,首先根据 URL 决定由那个函数来处理,然后在函数中进行操作,取得所需的数据。再将数据传给相应的模板文件中,由Jinja2 负责渲染得到 HTTP 响应内容,然后由Flask返回响应内容。
from flask import Flask from flask import render_template, redirect, url_for, request, session import config from functools import wraps # from model import User,Comment,Question # from exts import db from sqlalchemy import or_, and_ from flask_sqlalchemy import SQLAlchemy from datetime import datetime from werkzeug.security import generate_password_hash, check_password_hash # 密码保护,使用hash方法 app = Flask(__name__)# 创建Flask对象 app.config.from_object(config) # 关联config.py文件进来 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) author_id = db.Column(db.Integer, db.ForeignKey('user.id')) title = db.Column(db.String(225), nullable=False) detail = db.Column(db.Text, nullable=False) time = db.Column(db.DateTime, default=datetime.now()) 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')) 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=time.desc)) # order_by=creat_time.desc按时间降序 author = db.relationship('User', backref=db.backref('comments')) # 增加数据 # user = User(username='vae', password='5201314') # db.session.add(user) # db.session.commit() # # # # 查询数据 # user = User.query.filter(User.username == 'vae').first() # print(user.username,user.password) # # #修改数据 # user.password = '250250' # db.session.commit() db.create_all()# 测试是否连接成功 # 将数据库查询结果传递到前端页面 Question.query.all(),问答排序 @app.route('/') def index(): context = { 'questions': Question.query.order_by('-time').all() } return render_template('index.html', **context) @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'GET': return render_template('login.html') else: usern = request.form.get('username') passw = request.form.get('password') user = User.query.filter(User.username == usern).first() if user: if user.check_password(passw): session['user'] = usern session['id'] = user.id session.permanent = True return redirect(url_for('index')) # 重定向到首页 else: return u'password error' else: return u'username is not existed' # 定义上下文处理器 @app.context_processor# 上下文处理器,定义变量然后在所有模板中都可以调用,类似idea中的model def mycontext(): usern = session.get('user') if usern: return {'username': usern}# 包装到username,在所有html模板中可调用 else: return {} # 返回空字典,因为返回结果必须是dict # 跳转某页面之前先进行登录。定义decorator可以增强函数功能,装饰器本身是函数,入参是函数,返回值也是函数 def loginFrist(func): @wraps(func) # 加上wraps,它可以保留原有函数的__name__,docstring def wrappers(*args, **kwargs): # 定义wrapper函数将其返回,用*args, **kwargs把原函数的参数进行传递 if session.get('user'): # 只有经过登陆,session才能记住并get到值 return func(*args, **kwargs) else: return redirect(url_for('login')) return wrappers # 跳转注销 @app.route('/logout') def logout(): session.clear()# 注销时删除所有session return redirect(url_for('index')) # 注册 @app.route('/register', methods=['GET', 'POST']) def register(): if request.method == 'GET': return render_template('register.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: user = User(username=username, password=password) # 将对象接收的数据赋到User类中,即存到数据库 db.session.add(user) # 数据库操作 db.session.commit() return redirect(url_for('login')) # 重定向到登录页 # 问答页面 @app.route('/question', methods=['GET', 'POST']) @loginFrist# 将decorator定义的增强函数放在待增强函数定义的上面 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 = Question(title=title, detail=detail, author_id=author_id) db.session.add(question) db.session.commit() return redirect(url_for('index')) # 重定向到登录页 @app.route('/detail/<question_id>') def detail(question_id): quest = Question.query.filter(Question.id == question_id).first() comments = Comment.query.filter(Comment.question_id == question_id).all() return render_template('detail.html', ques=quest, comments=comments) # 读取前端页面数据,保存到数据库中 @app.route('/comment/', methods=['POST']) @loginFrist 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)) # 个人中心 @app.route('/usercenter/<user_id>/<tag>') @loginFrist def usercenter(user_id, tag): user = User.query.filter(User.id == user_id).first() context = { 'user': user } if tag == '1': return render_template('usercenter1.html', **context) elif tag == '2': return render_template('usercenter2.html', **context) else: return render_template('usercenter3.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) ) ).order_by('-time') return render_template('index.html', questions=ques) if __name__ == '__main__': app.run(debug=True)