Python+Flask+MysqL的web建设技术过程
Posted 肥牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python+Flask+MysqL的web建设技术过程相关的知识,希望对你有一定的参考价值。
前言
本人在一学期时间实现了Python+Flask+MysqL的web建设,页面具有简单的登录注册发布文章搜索文章等功能。
实现此页面所有的static文件、templates文件与py文件
这里的界面都为继承父模板后的界面.后面将会有相关介绍
2.登录界面
3.注册界面
3.发布问答界面
from flask import Flask app = Flask(__name__) @app.route(\'api/test\') def hello(): return \'Hello World!\' if __name__ == \'__main__\': app.run()
四、加载静态文件,父模板与其他界面的继承
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 %}
以下有如下13个步骤:
五、数据库连接池
数据库工具:mysql
1.安装与配置python3.6+flask+mysql数据库
1.下载安装MySQL数据库
2.下载安装MySQL-python 中间件(pip install flask-sqlalchemy (Python的ORM框架SQLAlchemy))
2.mysql创建数据库
3.数据库配置信息config.py
SQLALCHEMY_DATABASE_URI = \'mysql+pymysql://root:@localhost:3306/zhuce?charset=utf8\' SQLALCHEMY_TRACK_MODIFICATIONS = False
4.建立mysql和app的连接
from flask import Flask from flask_sqlalchemy import SQLAlchemy import config 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()
5.创建用户模型
六、通过用户模型,对数据库进行增删改查
from flask import Flask from flask_sqlalchemy import SQLAlchemy import config 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() #增 user=User(username=\'liu1234\',password=\'123456789\') db.session.add(user) db.session.commit() #删 user=User.query.filter(User.username==\'two1234\').first() user.password=\'12345678910\' db.session.delete(user) db.session.commit() #改 user=User.query.filter(User.username==\'two1234\').first() user.username=\'three1234\' db.session.add(user) db.session.commit() #查 user=User.query.filter(User.username==\'two1234\').first() print(user.id,user.username,user.password) @app.route(\'/\') def hello_world(): return \'Hello World!\' if __name__ == \'__main__\': app.run()
七、完成注册功能
- 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\'))
八、完成登录功能
1.js:设置return
function myLogin() { var oUname=document.getElementById("uname"); var oPass=document.getElementById("upass"); var oError=document.getElementById("error_box"); oError.innerHTML="<br>"; //username if(oUname.value.length<6||oUname.value.length>20){ oError.innerHTML="username must be 6-20."; return false; }else if((oUname.value.charCodeAt(0)>=48)&&(oUname.value.charCodeAt(0)<=57)){ oError.innerHTML="firt name can\'t numbuter."; 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="only number and letter"; return false; } } if(oPass.value.length<6||oPass.value.length>20){ oError.innerHTML="password must be 6-20."; return false; } return true; // window.alert("Login Successful") }
2.html:设置
1.form
2.input
3.onclick="return fnLogin()"
{% extends\'base.html\' %} {% block title %} Login {% endblock %} {% block head %} <script src="{{ url_for(\'static\',filename=\'js/denglu1.js\') }}"></script> <link rel="stylesheet" href="{{ url_for(\'static\',filename=\'css/denglu1.css\')}}"> {% endblock %} {% block main %} <body> <div class="login"> <h1>Login</h1> <form class="form" method="post" action="{{ url_for(\'sign_in\') }}"> <p class="field"> <input id="uname" type="text" name="username" placeholder="Username" required/> <i class="fa fa-user"><img src="../static/images/daohang1.jpg" width="44px" height="auto"></i> </p> <p class="field"> <input id="upass" type="password" name="password" placeholder="Password" required/> <i class="fa fa-lock"><img src="../static/images/daohang1.jpg" width="44px" height="auto"></i> </p> <button class="button" onclick="return myLogin()">Login</button> <div id="error_box"><br></div> </form> </div> </body> {% endblock %} </html>
3.py:
1.@app.route设置methods
2.GET
3.POST
1.读取表单数据
2.查询数据库
1.用户名密码对:
1.记住用户名
2.跳转到首页
1.用户名密码不对:
1.提示相应错误。
from flask import Flask,render_template,request,redirect,url_for,session from flask_sqlalchemy import SQLAlchemy import config 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) #db.create_all() @app.route(\'/\') def home(): return render_template(\'shouye.html\') @app.route(\'/sign_in/\',methods=[\'GET\',\'POST\']) def sign_in(): if request.method == \'GET\': return render_template(\'denglu1.html\') else: username = request.form.get(\'username\') password = request.form.get(\'password\') user = User.query.filter(User.username == username).first() if user: if user.password == password: session[\'user\']=username session.permanent = True return redirect(url_for(\'home\')) else: return \'password error\' else: return \'username is not existed.\' @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\')) @app.route(\'/question/\') def question(): return render_template(\'question.html\') if __name__ == \'__main__\': app.run(debug=True)
3.session:
1.从`flask`中导入`session`
2.设置`SECRET_KEY`
3.操作字典一样操作`session`:增加用户名`session[\'username\']=`username
import os SECRET_KEY = os.urandom(24) SQLALCHEMY_DATABASE_URI = \'mysql+pymysql://root:@localhost:3306/zhuce?charset=utf8\' SQLALCHEMY_TRACK_MODIFICATIONS = False
九、登录后更新导航
- 用上下文处理器app_context_processor定义函数
- 获取session中保存的值
- 返回字典
app = Flask(__name__) app.config.from_object(config) db=SQLAlchemy(app)
@app.context_processor def mycontext(): username=session.get(\'user\') if username: return {\'username\':username} else: return {}
2.在父模板中更新导航,插入登录状态判断代码。
- 注意用{% ... %}表示指令。
- {{ }}表示变量
<div> {% if username %} <a href="#" style="margin-right: -10px;color:deepskyblue">{{ username }}</a> <a href="{{ url_for(\'logout\') }}" >注销</a> {% else %} <a href="{{ url_for(\'sign_in\') }}" style="margin-right: -10px">登录</a> <a href="{{ url_for(\'sign_up\') }}" >注册</a> {% endif %} </div>
3.完成注销功能。
- 清除session
- 跳转
@app.route(\'/logout/\') def logout(): session.clear() return redirect(url_for(\'shouye\'))
十、完成发布功能(与注册登录功能相似)
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.完成发布函数。
保存到数据库。
重定向到首页
十一、在首页显示问答列表(用户可自行选择显示内容,本文以显示问答列表为例)
1. 在首页添加显示问答的列表,并定义好相应的样式。
无序列表
<ul >
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
2. 用字典向index.html传递参数。
- 首页列表显示全部问答:
- 将数据库查询结果传递到前端页面 Question.query.all()
- 前端页面循环显示整个列表。
- 问答排序
- 完成问答详情页布局:
- 包含问答的全部信息
- 评论区
- 以往评论列表显示区。
- 在首页点击问答标题,链接到相应详情页。
十二、从首页问答列表标题链接到详情页
- 主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 }}{{ ques.author.username }}
{{ ques.detail }} -
建立评论的对象关系映射:
class Comment(db.Model):
__tablename__=\'comment\'
十三、实现发布评论
1.定义评论的视图函数
@app.route(\'/comment/\',methods=[\'POST\'])
def comment():
读取前端页面数据,保存到数据库中
@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))
2.用<input type="hidden" 方法获取前端的"question_id"
3.显示评论次数
4.要求评论前登录
{% extends\'base.html\' %} {% block title %} Home {% endblock %} {% block head %} <link rel="stylesheet" href="{{ url_for(\'static\',filename=\'css/question_detail.css\')}}" type="text/css"> {% endblock %} {% block main %} <body> <div class="detail"> <div class="detail_left"> <h2>{{ question.title }}</h2> <a class="username">{{ question.author.username }}</a> <span class="badge">{{ question.creatTime }}</span> <hr> <a style="white-space: pre-wrap" >{{ question.detail }}</a> <hr> <form action="{{ url_for(\'comment\') }}" method="post"> <textarea name=\'detail\' class="form-control" rows="6" id="questionDetail"></textarea> <br> <button class="btn-default">发布</button> <input name="question_id" value="{{ question.id }}" type="hidden" /> </form> <p class="comment_num"><img class="heart" src="../static/images/heart.png">[{{ question.comments|length }}]</p> <ul class="comment"> {% for foo in question.comments %} <span class="icon" aria-hidden="true"><img src="../static/images/icon.jpg"></span> <a href="#" class="name">{{ foo.author.username }}</a> <span class="badge2">{{ foo.creatTime }}</span> <br> <p class="neirong">{{ foo.detail }}</p> {% endfor %} </ul> </div> </div> </body> {% endblock %}
十四、完成个人中心相关信息
- 个人中心—视图函数带标签页面参数tag
- @app.route(\'/usercenter/<user_id>/<tag>\')
def usercenter(user_id, tag):
if tag == ‘1\':
return render_template(\'usercenter1.html\', **context)
@app.route(\'/self/<user_id>/<tag>\') @loginFirst def self(user_id,tag): user=User.query.filter(User.id==user_id).first() context={ \'user\':user } if tag==\'1\': return render_template(\'allquestion.html\',**context) elif tag==\'2\': return render_template(\'allcomments.html\',**context) else: return render_template(\'information.html\',**context)
3.个人中心—导航标签链接增加tag参数
<li role=“presentation”><a href=“{{ url_for(‘usercenter’,user_id = user.id,tag = ‘1’) }}">全部问答</a></li>
<li role="presentation"><a href="{{ url_for(\'self\',user_id=user.id,tag=\'1\') }}">全部问答</a> </li> <li role="presentation"><a href="{{ url_for(\'self\',user_id=user.id,tag=\'2\') }}">全部评论</a> </li> <li role="presentation"><a href="{{ url_for(\'self\',user_id=user.id,tag=\'3\') }}">个人信息</a> </li>
4.个人中心—有链接到个人中心页面的url增加tag参数
<a href="{{ url_for(\'usercenter\',user_id = session.get(\'userid\'), tag=1) }}">{{ session.get(\'user\') }}</a>
十五、实现导航条中的搜索功能
1.修改base.html 中搜索输入框所在的
- <form action="{{ url_for(\'search\') }}" method="get">
- <input name="q" type="text" placeholder="请输入关键字">
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/\') def search(): qu=request.args.get(\'q\') ques=Question.query.filter( or_( Question.title.contains(qu), Question.detail.contains(qu) ) ).order_by(\'-creatTime\') return render_template(\'shouye.html\',question=ques)
十六、密码保护
以上是关于Python+Flask+MysqL的web建设技术过程的主要内容,如果未能解决你的问题,请参考以下文章Python+Flask+MysqL的web建设技术开发一个网站
沿用Python+Flask+Mysql的web建设技术开发网站