Python语言由于开发迅速,语法简单,可移植等特点越来越受到大众的喜爱。Python Web常用的开发框架包括Django,Flask,Tornado,Bottle,web.py,Quixote等。其中,Flask较其它更为轻巧,也最容易上手。我这学期刚好学习了使用Python的Flask框架+MysqL搭建简单的web项目,实现了具有登录注册发布评论功能的简单的页面。以下是我这学期的学习成果和学习经验,如有不足之处还望指正。
1.首先则是认识URL,观察那些常用网站的网址,区分它们不同组成部分,观察web的浏览过程。然后,认识div块与form表单的作用,利用div块与form表单制作登录页面。练习使用各种列表,如下拉列表选择框、无序列表、有序列表以及定义列表。 观察常用网页的HTML元素,并在实操过程中,用已学的标签模仿制作。我制作网页的第一步是制作一个导航条。首先认识HTML头部元素:<base> 定义了页面链接标签的默认链接地址;<style> 定义了HTML文档的样式文件;<link> 定义了一个文档和外部资源之间的关系。练习样式表:行内样式表、内嵌样式表、外部样式表,和定义三类选择器:HTML 选择器、CLASS 类选择器、ID 选择器。
<div id="content" style="background-color:#EEEEEE;height:150px;width:400px;float:left;"align="center">
<form>
</form>
</div>
2.制作了导航条之后,则需要实现样式的美化,这就需要用到CSS知识点的运用。首先要认识CSS的 盒子模型,了解CSS选择器的灵活使用。CSS可以通过三种方式实现:第一,图片文字用div等元素布局形成HTML文件;第二,新建相应CSS文件,并link到html文件中;第三,在HTML中的head标签中使用style标签块进行布局美化,如:
img{
width:200px;
}
.img{
border: 1px solid #eeeeee;
width: 180px;
float:left;
margin:10px;
}
.img img{
width:100%;
height: auto;
}
img.hover{
border: 1px solid#777777;
}
3.了解了HTML基础以及CSS基础后,同时还需要了解JS基础。同CSS一样,<script></script>也存在三种用法:放在<body>中、放在<head>中、放在外部JS文件中。同时还需要了解三种输出数据的方式:使用 document.write() 方法将内容写到 HTML 文档中、使用 window.alert() 弹出警告框、使用 innerHTML 写入到 HTML 元素。用 "id" 属性来标识 HTML 元素、用document.getElementById(id) 方法访问 HTML 元素、用innerHTML 来获取或插入元素内容。做好登陆页面准备:增加错误提示框、写好HTML+CSS文件、设置每个输入元素的id。使用onclick调用这个函数。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
<link href="../static/css/login.css" rel="stylesheet" type="text/css">
<script>
function fnLogin() {
var oUname = document.getElementById("uname")
var oError = document.getElementById("error_box")
var oUpass = document.getElementById("upass")
if(oUname.value.length<6){
oError.innerHTML="用户名至少为6位"
}
if(oUname.value.length>20){
oError.innerHTML="用户名不得超过20位"
}
if(oUname.value.length>6&oUname.value.length<20&oUpass.value.length<6){
oError.innerHTML="密码至少为6位"
}
if(oUname.value.length>6&oUname.value.length<20&oUpass.value.length>20){
oError.innerHTML="密码不得超过20位"
}
}
</script>
</head>
<body>
<div class="flex-container">
<div class="box">
<h2>登陆页面</h2>
<div class="input_box">账户:<input id='uname' type="text" placeholder="请输入登录名"></div>
<div class="input_box">密码:<input id='upass' type="password" placeholder="请输入密码"></div><br>
<div id="error_box"><br></div>
<div class="input_box">
<div class="input_box"><button onclick="fnLogin()">登录</button>
<button onclick=window.alert("取消将不保存对此页面的更改")>取消</button></div>
</div>
<br>
</div>
</div>
</body>
</html>
制作父模板html,包括顶部导航、中间区块划分、底部导航、底部说明等。汇总相关的样式形成独立的css文件。汇总相关的js代码形成独立的js文件。形成完整的base.html+css+js。
完成以上所有,就可以开始flask项目了。第一步,新建一个Flask项目,设置调试模式。在理解了Flask项目主程序以后,第二步,使用装饰器,设置路径与函数之间的关系。使用Flask中render_template,用不同的路径,返回首页、登录员、注册页。第三步,用视图函数反转得到URL,url_for(‘login’),完成导航里的链接。
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/login/')
def login():
return render_template('login.html')
if __name__ == '__main__':
app.run(debug=True)
<li><a href="{{ url_for('login') }}" onclick="">登陆</a></li>
4.用url_for加载静态文件,使用方法:<script src="{{ url_for('static',filename='js/login.js') }}"></script> 。flask 从static文件夹开始寻找,可用于加载css, js, image文件。父模板继承和扩展:首先把一些公共的代码放在父模板中,避免每个模板写同样的内容。再用子模板继承父模板,使用方法:{% extends 'base.html’ %} 。父模板可以提前定义好子模板可以实现一些自己需求的位置及名称。
<title>{% block title %}标题{% endblock %}</title>
{% block head %}头部{% endblock %}
{% block main %}内容{% endblock %}
{% block title %}登录{% endblock %} 前面我们做的页面都按上述步骤改写。
5.接下来是连接Mysql数据库,第一步是建立数据库配置信息config.py,第二步,建立mysql和app的连接,最后创建用户模型。
from flask import Flask
import config
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_object(config)
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(20), nullable=False)
nickname = db.Column(db.String(20))
db.create_all()
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:@127.0.0.1:3306/mis_db?charset=utf8'
SQLALCHEMY_TRACK_MODIFICATIONS = False
6.通过用户模型,我们可以队数据库进行增删改查操作。
user=User(username='mis0106',password='123456')
db.session.add(user)
db.session.commit()#增
user=User.query.filter(User.username=='mis0106').first()
print(user.username,user.password)
db.session.commit()#查
user=User.query.filter(User.username=='mis0106').first()
user.password='654321'
db.session.commit()#改
user=User.query.filter(User.username=='mis0106').first()
db.session.delete(user)
db.session.commit()#删
7.完成注册功能。分别在js文件、html文件和主py文件进行设置。
js文件: onclick函数return True时才提交表单,return False时不提交表单。
html文件:<form>中设置 action和method="post"
<input> 中设置 name 。
主py文件中:rom flask import request, redirect, url_for
@app.route('/regist/', methods=['GET', 'POST’])
def regist():
if request.method == 'GET':
return render_template('regist.html')
else:
username = request.form.get(‘username’)#获取form中的数据
判断用户名是否存在:存在报错
不存在,存到数据库中
redirect重定向到登录页
8.完成登录功能,用session记住用户名。分别在js文件、html文件和主py文件进行设置。
js文件:设置onclick函数return True时才提交表单,return False时不提交表单。
html文件:<form>中设置 action和method="post"
<input> 中设置 name 。
onclick=“return fnLogin()”
主py文件:@app.route设置methods
GET
POST
- 读取表单数据查询数据库
- 用户名密码对:
- 记住用户名
- 跳转到首页
- 用户名密码不对:
- 提示相应错误。
session:
- 从`flask`中导入`session`
- 设置`SECRET_KEY`
- 操作字典一样操作`session`:增加用户名`session['username']=`username
9.完成发布功能
为了网站的安全和方便网站的管理。在发布之前我们要先定义一个装饰器。
- 编写要求登录的装饰器
from functools import wraps
def loginFirst(func): #参数是函数
@wraps(func)
def wrapper(*args, ** kwargs): #定义个函数将其返回
#要求登录
return func(*args, ** kwargs)
return wrapper #返回一个函数
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
- 应用装饰器,要求在发布前进行登录,登录后可发布。
@app.route('/question/',methods=['GET','POST'])
@loginFirst
def question():
- 建立发布内容的对象关系映射。
class Question(db.Model):
class Question(db.Model):
__tablename__='question'
id=db.Column(db.INTEGER,primary_key=True,autoincrement=True)
title=db.Column(db.String(100),nullable=False)
datail=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'))
- 完成发布函数。
保存到数据库。
重定向到首页。
完成发布功能后,从首页问答标题到问答详情页:
主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 }}
建立评论的对象关系映射。 class Comment(db.Model):
__tablename__='comment'
10.完成评论功能
定义评论的视图函数
@app.route('/comment/',methods=['POST'])
def comment():
读取前端页面数据,保存到数据库中
用<input type="hidden" 方法获取前端的"question_id"
显示评论次数
要求评论前登录
@app.route('/comment/',methods=['GET','POST'])
@loginFirst
def comment():
if request.method == 'GET':
return render_template('question_detail.html')
else:
detail = request.form.get('detail')
author_id =User.query.filter(User.username == session.get('user')).first().id
question_id=request.form.get('question_id')
comments = Comment(detail=detail,author_id=author_id,question_id=question_id)
db.session.add(comments)
db.session.commit()
return redirect(url_for('question_detail',question_id=question_id))
11.实现搜索功能。
准备视图函数search()
修改base.html 中搜索输入框所在的<form> <input>
<form action="{{ url_for('search') }}" method="get">
<input type="text" name="q" PLACEHOLDER="请输入关键字">
</form>
完成视图函数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)
组合条件查询
from sqlalchemy import or_, and_
@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('-creat_time')
return render_template('shouye.html',question=ques)
12.最后实现密码保护功能。
更新User对象,设置对内的_password
编写对外的password
密码验证的方法:def check_password(self, row_password): #密码验证
result = check_password_hash(self._password,row_password)
return result
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
登录验证:password1 = request.form.get('password')
user = User.query.filter(User.username == username).first()
if user:
if user.check_password(password1):
以上就是我使用Python的Flask框架+MysqL完成简单的web项目的全过程。