1.我的學期總結 :通過一個學期的學習我對Python有了必定程度的認識,這些認識離不開杜雲梅老師的手把手教學在此謝謝老師一個學期對咱們的付出。前期接觸Python是經過老師上課解析什麼是Python,信息管理系統這門課主要學什麼而後慢慢融入代碼教學。一開始從基礎開始咱們學習了Python的基礎語法,輸入、輸出、交互、數字計算的方法、字符串基本操做、凱撒密碼、自制九九乘法表、中英文詞頻統計等,還學習了import turtle庫,並利用這個庫繪製出多種多樣的圖形使咱們更有興趣繼續學習下去。而後咱們就學習了中期學習了web基礎,用html元素製做web界面。練習使用下拉列表選擇框、無序列表、有序列表、定義列表。開始製做本身的導航條。練習樣式表:行內樣式表、內嵌樣式表、外部樣式表。後期咱們開始了Flask項目,加載靜態文件,父模板的繼承和擴展,鏈接mysql數據庫,建立用戶模型,創建mysql和app的鏈接。經過用戶模型,對數據庫進行增刪改查操做。完成註冊功能,將界面的數據存到數據庫,redirect重定向登陸頁。完成登陸功能,用session記住用戶名,增長用戶名。登陸以後更新導航。在父模板中更新導航,插入登陸狀態判斷代碼。完成註銷功能,清除session。發佈功能的實現,製做首頁的顯示列表,首頁列表顯示所有問答,完成問答詳情頁佈局,從首頁問答標題到問答詳情頁,完成評論功能,完成評論列表顯示及排序,我的中心顯示,我的中心標籤頁導航,完成我的中心—導航標籤,實現搜索功能(包括高級搜索等),最重要的是實現密碼加密功能。還作了模型分離與數據遷移,讓數據管理更加高效簡潔還使用Flask中render_template,用不一樣的路徑,返回首頁、登陸員、註冊頁。用視圖函數反轉獲得URL,url_for(‘login’),完成導航裏的連接。加載靜態文件,進行父模板的繼承和擴展,實現本身代碼的需求。在學習Python+Flask+MysqL的web建設時,須要安裝數據庫(mysql)、開發工具(pycharm)和開發須要用到的第三方庫。
css
2.總結Python+Flask+MysqL的web建設技術過程:html
導航欄和首頁mysql
註冊頁面web
登陸頁面sql
發佈問答頁面數據庫
問答詳情頁flask
我的中心bootstrap
主要代碼:session
from flask import Flask, render_template, redirect, url_for,request,session from flask_sqlalchemy import SQLAlchemy from datetime import datetime from functools import wraps from sqlalchemy import or_,and_ import config from werkzeug.security import generate_password_hash,check_password_hash app = Flask(__name__) app.config.from_object(config) db = SQLAlchemy(app) #建立用戶模型 class User(db.Model): __table__name = '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_passwprd): result = check_password_hash(self._password, row_passwprd) 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) create_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')) create_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=create_time.desc)) author = db.relationship('User',backref = db.backref('comments')) db.create_all() ''' 增長 user = User(username='qingting',password='123') db.session.add(user) db.session.commit() 查詢 user = User.query.filter(User.username == 'qingting').first() print(user.username,user.password) 修改 user=User.query.filter(User.username == 'qingting').first() user.password=1234567 db.session.commit() 刪除 user=User.query.filter(User.username == 'qingting').first() db.session.delete(user) db.session.commit() '''
導航欄首頁的html代碼(用於其餘網頁的繼承):app
<!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/basic.css') }}" base href="" target="_blank">#} <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> {% if username %} <a href="{{ url_for('usercenter',user_id = session.get('userid'),tag=1) }}">{{ session.get('user') }}</a> {% else %} <div class="container"> <div class="row clearfix"> <div class="col-md-12 column"> <nav class="navbar navbar-default" role="navigation"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button> <a class="navbar-brand" href="#">carrie</a> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li> <a href="{{ url_for('index') }}">首頁</a> </li> <li> <a href="{{ url_for('question') }}">發佈問答</a> </li> <li> <a href="{{ url_for('login') }}">登陸</a> </li> <li> <a href="{{ url_for('regist') }}">註冊</a> </li> <li> <a href="{{ url_for('logout') }}">註銷</a> </li> </ul> <form action="{{ url_for('search') }}" method="get" class="navbar-form navbar-left" role="search"> <div class="form-group"> <input name="q" type="text" class="form-control" placeholder="請輸入關鍵字"/> </div><button type="submit" class="btn btn-default">搜索</button> {% endif %} </form> <script> function mySwitch() { var oBody = document.getElementById("myBody"); var oOnOff = document.getElementById("myOnOff"); if(oOnOff.src.match("bulbon")){ oOnOff.src="http://www.runoob.com/images/pic_bulboff.gif"; oBody.style.background="black"; oBody.style.color="darksalmon"; }else { oOnOff.src="http://www.runoob.com/images/pic_bulboff.gif"; oBody.style.background="darksalmon"; oBody.style.color="black"; } } </script> <img id="myOnOff" onclick="mySwitch()" src="http://www.runoob.com/images/pic_bulbon.gif" width="30px";> </div> </nav> </div> </div> </div> {% block main %} {% endblock %} </head> <body id="myBody"> </body> </html>
註冊頁面的代碼:
{% extends'base.html' %} {% block title %}註冊{% endblock %} {% block head %} <script src="{{ url_for('static',filename='js/regist.js') }}"></script> {% endblock %} {% block main %} <style> .input_box { width: 325px; height: 50px; padding-left: 7px; padding-right: 7px; background: none; line-height: 30px; font-size: 16px; {# color: bisque;#} vertical-align: middle; } .box{ align-content: center; background-color: cadetblue; height:450px;width:400px;float:left; text-align: center; vertical-align: middle; position: absolute; top: 50%; left: 50%; margin: -150px 0 0 -150px; border: 1px solid #ccc; border-radius: 20px; } .jj{ width: 78px; margin: 10px 0; padding: 8px 18px; font-size: 20px; border: none; border-radius: 20px; color: #fff!important; background-color: darkslateblue; cursor: pointer; outline: none; } body { background-color: #ffffff; } .dd{ font-size:28px; color: #fff; } </style> <div class="box"> <h2 class="dd">註冊</h2> <form action="{{ url_for('regist') }}" method="post"> <div class="input_box"> 用戶名:<input id="uname" type="text" placeholder="請輸入用戶名" name="username"> </div> <div class="input_box"> 手機號:<input id="uphonenumeber" type="text" placeholder="請輸入手機號" name="userphone"> </div> <div class="input_box"> 郵 箱: <input id="uemaill" type="text" placeholder="請輸入郵箱" name="useremail"> </div> <div class="input_box"> 密 碼: <input id="upassworld" type="password" placeholder="請輸入密碼" name="password"> </div> <div class="input_box"> 確認密碼:<input id="upassworld1" type="password" placeholder="請再次輸入密碼"> </div> <div id="error_box"><br></div> <div> <button class="jj" onclick="fnRegist()">確認註冊</button> </div> </form> </div> {% endblock %}
註冊的js文件:
function fnRegist() { var oUame = document.getElementById("uname") var oError = document.getElementById("error_box") var oPass = document.getElementById("upassworld").value; var oPass1 = document.getElementById("upassworld1").value; var isoError = true; oError.innerHTML = "<br>" //uname if (oUame.value.length<6 || oUame.value.length>20) { oError.innerHTML = "用戶名爲6-10位"; isError = false; return isoError; }else if((oUame.value.charCodeAt(0)>=48) && (oUame.value.charCodeAt(0)<=57) ){ oError.innerHTML="用戶名首字母不能是數字"; isError = false; return isoError; }else for(var i=0; i<oUame.value.length;i++){ if((oUame.value.charCodeAt(i)<48||(oUame.value.charCodeAt(i)>57)&&(oUame.value.charCodeAt(i)<97 || (oUame.value.charCodeAt(i)>122)))){ oError.innerHTML="只能是數字或字母"; isError = false; return isoError; } } //upassword if(opass.value.length<6 || opass.value.length>20){ oError.innerHTML = "密碼爲6-20位"; isError = false; return isoError; } if (oPass!=oPass1){ document.getElementById("error_box").innerHTML = "兩次密碼不一致" isError = false; return isoError; } return isoError; window.alert("註冊成功!") }
註冊頁面用到的函數:
@app.route('/regist/' , methods=['GET','POST']) def regist(): if request.method == 'GET': return render_template('regist.html') else: username = request.form.get('username')# 獲取form中的數據 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) db.session.add(user)#數據庫操做 db.session.commit() return redirect(url_for('login'))#從新到登陸頁
登陸頁面代碼:
{% extends'base.html' %} {% block title %}登陸{% endblock %} {% block head %} <script src="{{ url_for('static',filename='js/login.js') }}"></script> {% endblock %} {% block main %} <style> .input_box { width: 325px; height: 50px; padding-left: 7px; padding-right: 7px; background: none; line-height: 30px; font-size: 16px; {# color: bisque;#} vertical-align: middle; } .box{ align-content: center; background-color: cadetblue; height:260px;width:340px;float:left; text-align: center; vertical-align: middle; position: absolute; top: 50%; left: 50%; margin: -150px 0 0 -150px; border: 1px solid #ccc; border-radius: 20px; } .jj{ width: 78px; margin: 10px 0; padding: 8px 18px; font-size: 20px; border: none; border-radius: 20px; color: #fff!important; background-color: darkslateblue; cursor: pointer; outline: none; } body { background-color: #ffffff; } .dd{ font-size:28px; color: #fff; } </style> <div class="box"> <h2 class="dd">登陸</h2> <form action="{{url_for('login')}}" method="post"> <div class="input_box"> 用戶名:<input id="username" type="text" placeholder="請輸入用戶名" name="username"> </div> <div class="input_box"> 密 碼: <input id="userpassworld" type="password" placeholder="請輸入密碼" name="password"> </div> <div id="error_box"><br></div> <div> <button class="jj" onclick="fnLogin()">登陸</button> </div> </form> </div> {% endblock %}
登陸的js:
function fnLogin() { var oUame = document.getElementById("uname"); var opass = document.getElementById("upassworld"); var oError = document.getElementById("error_box"); var isError = true; oError.innerHTML = "<br>"; //uname if (oUame.value.length<6 || oUame.value.length>20) { oError.innerHTML = "用戶名爲6-10位"; isError = false; return isError; }else if((oUame.value.charCodeAt(0)>=48) && (oUame.value.charCodeAt(0)<=57) ){ oError.innerHTML="用戶名首字母不能是數字"; isError = false; return isError; }else { for(var i=0; i<oUame.value.length;i++){ if((oUame.value.charCodeAt(i)<48||(oUame.value.charCodeAt(i)>57)&&(oUame.value.charCodeAt(i)<97 || (oUame.value.charCodeAt(i)>122)))){ oError.innerHTML="只能是數字或字母"; isNotError = false; return isError; } } } //upassword if(opass.value.length<6 || opass.value.length>20){ oError.innerHTML = "密碼爲6-20位"; isError = false; return isError; } return isError; window.alert("登陸成功!") }
登陸頁面用到的函數:
@app.route('/login/' , methods=['GET','POST']) def login(): if request.method == 'GET' : return render_template('login.html') else: username = request.form.get('username')# 獲取form中的數據 password1 = request.form.get('password') user = User.query.filter(User.username == username).first() if user: if user.check_password(password1): session['user'] = username session['userid'] = user.id session.permanent = True return redirect(url_for('index')) else: return u'password error' else: return u'username is not existed.' return redirect(url_for('index')) # 返回首頁
詳情頁面的html:
{% extends'base.html' %} {% block title %}首頁-{% endblock %} {% block head %}{% endblock %} {% block main %} <style> body{ background-color: #ffffff; } .footer{ bottom: 0; width: 100%; } div.img{ border: 1px solid #212ccc; width:100px; float: left; margin: 5px; } div.img img{ width: 100%; height: auto; } div,desc{ text-align: center; padding: 5px; } div,img:hover{ border: 1px solid #ffffff; } </style> {# <img src="{{ url_for('static',filename='images/問答.jpg') }}" alt="" width="100">#} <p>{{ usern }}</p> {% for foo in questions %} <ul class="new-list"> <li> <p>{{ foo.detail }}</p> <a target="_self" href="{{ url_for('detail',question_id=foo.id) }}">標題:{{ foo.title }}</a><br> <a href="{{ url_for('usercenter',user_id = foo.author.id,tag = 1) }}">發佈者:{{ foo.author.username }}<br></a> 評論:({{ foo.comments|length }})<br> <span class="post_item_foot"> 發佈於 {{ foo.create_time }} </span> </li> </ul> </div> <hr></div> {% endfor %} {% block body %} <div> <div class="recommend"> <footer class="footer"> <div class="img"> <img src="{{ url_for('static',filename='images/timg.jpg') }}" alt="" width="100"> <div class="desc"><a href="https://image.baidu.com/search/detail?ct=503316480&z= 0&ipn=d&word=%E5%B8%83%E6%9C%97%E7%86%8A&step_word=&hs=2&pn=6&spn=0&di= 79837637440&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in= &cl=2&lm=-1&st=undefined&cs=4254122511%2C4041747366&os=2092177177%2C2042104883&simid= 4288902954%2C717627127&adpicid=0&lpn=0&ln=1971&fr=&fmq=1514876043235_R&fm=&ic= undefined&s=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face= undefined&ist=&jit=&cg=&bdtype=0&oriquery=&objurl=http%3A%2F%2Fimg4.duitang.com% 2Fuploads%2Fitem%2F201604%2F09%2F20160409191430_AWUck.jpeg&fromurl=ippr_z2C%24qAzd H3FAzdH3Fooo_z%26e3B17tpwg2_z%26e3Bv54AzdH3Fks52AzdH3F%3Ft1%3Dccblnb0a9&gsm= 0&rpstart=0&rpnum=0">BROWN </a></div> </div> </footer> </div> </div> {% endblock %} {% endblock %}
詳情頁面的函數:
@app.route('/question/',methods=['GET', 'POST']) # 跳轉註冊,methods定義它有兩種請求方式 @loginFirst 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() return render_template('detail.html',ques = quest) @app.route('/comment/',methods=['POST']) @loginFirst 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))
用於我的中心繼承頁面:
{% extends 'user.html' %} {% block user %} <style> { background-color: antiquewhite; } </style> <script src="{{ url_for('static',filename='js/regist.js') }}"></script> <div class="page-header"> <h3><span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span>{{ user.username }} <br> <small>所有問答<span class="badge"></span></small> </h3> <ul class="list-group" style="margin: 10px"> {% for foo in user.question %} <li class="list-group-item"> <span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span> <a href="#">{{ foo.author.username }}</a> <span class="badge">{{ foo.create_time }}</span> <p>{{ foo.detail }}</p> </li> {% endfor %} </ul> </div> <div class="page-header"> <h3><span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span>{{ user.username }} <br> <small>所有評論<span class="badge"></span></small> </h3> <ul class="list-group" style="margin: 10px"> {% for foo in user.comments %} <li class="list-group-item"> <span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span> <a href="#">{{ foo.author.username }}</a> <span class="badge">{{ foo.create_time }}</span> <p>{{ foo.detail }}</p> </li> {% endfor %} </ul> </div> <div class="page-header"> <h3><span class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span>{{ user.username }} <br> <small>我的信息<span class="badge"></span></small> </h3> <ul class="list-group" style="margin: 10px"> <li class="list-group-item">用戶:{{ user.username }}</li> <li class="list-group-item">編號:{{ user.id }}</li> <li class="list-group-item">暱稱:{{ user.username }}</li> <li class="list-group-item">文章:</li> </ul> </div> {% endblock %}
我的中心調用的函數:
@app.route('/user/<user_id>/<tag>') @loginFirst def usercenter(user_id, tag): user = User.query.filter(User.id == user_id).first() context = { 'user':user # 'username':user.username, # 'questions':user.questions, # 'comments':user.comments } 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) # return render_template('usercenter.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), # Question.author_id.contains(qu) ) ).order_by('-create_time') return render_template('index.html',questions = ques)