通過一個學期的學習,在老師的教導之下,從一個連網頁製做都不會的菜鳥,變成會用Python+Flask+MysqL的web建設技術來製做網頁。css
一開始是學習簡單輸入輸出交互,算並輸出兩個數字之和,輸入半徑,計算圓的面積。到畫圓,太陽花,同心圓畫五角星,字符串基礎操做,愷撒密碼的編碼,打出99乘法表,英文詞頻統計,用文件方式實現完整的英文詞頻統計,中文詞頻統計,datetime處理日期和時間,timestamp與timedelta,這些都是比較簡單的,比較容易上手,逐漸的,web的基礎,用html元素製做web網頁,導航,css基礎,圖片導航塊,到登陸,登陸和註冊頁面的前端驗證再到鏈接myssql數據庫,建立用戶模型,對數據庫進行增刪改查操做,完成註冊功能,登陸後更新導航,發佈功能,製做首頁的顯示列表,顯示所有問答,完成問答詳情頁的佈局,點擊問答標題時跳轉到相應的詳情頁,評論功能的實現,我的中心的顯示,我的中心標籤導航,搜索功能的實現,密碼的保護等等。在學習的過程當中發現了不少樂趣。html
Python+Flask+MysqL的web建設技術過程前端
主py文件:python
from functools import wraps from flask import Flask, render_template, url_for, redirect, request, session import config from sqlalchemy import or_,and_ from exts import db from models import User,Question,Comment app = Flask(__name__) app.config.from_object(config) db.init_app(app) # db.create_all() # 增長 # user = User(username='tan1997',password='19961021') # db.session.add(user) # db.session.commit() # 查詢 # user = User.query.filter(User.username == 'tan1997').first() # print(user.username,user.password) # 修改 # user=User.query.filter(User.username == 'tan1997').first() # user.password=1234567 # db.session.commit() # 刪除 # user=User.query.filter(User.username == 'tan1997').first() # db.session.delete(user) # db.session.commit() @app.route('/') def index(): context = { 'question': Question.query.order_by('-create_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') password1 = request.form.get('password') user = User.query.filter(User.username == usern).first() if user: if user.check_password(password1): session['user'] = usern session['id'] = user.id session.permanent = True return redirect(url_for('index')) else: return '密碼錯誤' else: return '用戶名不存在' @app.context_processor def mycontext(): usern = session.get('user') if usern: return { 'susername': usern, } else: return {} def loginFirst(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('/regist/', methods=['GET', 'POST']) def regist(): if request.method == 'GET': return render_template("regist.html") else: username = request.form.get('username') password = request.form.get('password') nickname = request.form.get('nickname') user = User.query.filter(User.username == username).first() if user: return ' 用戶名已存在' else: user = User(username=username, password=password, nickname=nickname) db.session.add(user) # 數據庫,添加操做 db.session.commit() return redirect(url_for('login')) @app.route('/logout/') def logout(): session.clear() return redirect(url_for('index')) @app.route('/question/', methods=['GET', 'POST']) @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>') # 和idea的update同樣,將id帶到控制器 def detail(question_id): quest = Question.query.filter(Question.id == question_id).first() # 根據id查詢出整條元組記錄,丟進quest return render_template('detail.html', ques=quest) # 把值quest丟進鍵quest,在detail.html頁面調用 @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)) @app.route('/user/<user_id>/<tag>') @loginFirst def user(user_id, tag): user = User.query.filter(User.id == user_id).first() context = { 'user': user, 'username': user.username, 'questions': user.question, # 用反向定義的question '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) # # @app.route('/usercenter1/<user_id>') # def usercenter1(user_id): # user = User.query.filter(User.id == user_id).first() # context = { # 'username_id': user.id, # 'username': user.username, # 'questions': user.question, # 用反向定義的question # 'comments': user.comments # } # return render_template('usercenter1.html', **context) # # # @app.route('/usercenter2/<user_id>') # def usercenter2(user_id): # user = User.query.filter(User.id == user_id).first() # context = { # 'username_id': user.id, # 'username': user.username, # 'questions': user.question, # 用反向定義的question # 'comments': user.comments # } # # return render_template('usercenter2.html', **context) # # # @app.route('/usercenter3/<user_id>') # def usercenter3(user_id): # user = User.query.filter(User.id == user_id).first() # context = { # 'username_id': user.id, # 'username': user.username, # 'questions': user.question, # 用反向定義的question # 'comments': user.comments # } @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('-create_time') return render_template('index.html',question=ques) if __name__ == '__main__': app.run(debug=True)
models.py文件:mysql
from datetime import datetime from werkzeug.security import generate_password_hash,check_password_hash from exts import db 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) nickname = db.Column(db.String(50)) @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) 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')) # 反向定義一個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'))
exit.py文件:web
from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy()
manage.py文件:sql
from flask_script import Manager from flask_migrate import Migrate,MigrateCommand from myqa import app from exts import db from models import User,Question,Comment manager = Manager(app) # Manager只有一個參數:一個Flask實例 migrate = Migrate(app,db) # 使用Migrate綁定app和db # 添加遷移腳本命令 manager.add_command('db',MigrateCommand) # 加入命令,命令行輸入python manage.py db migrate if __name__ == '__main__': manager.run()
config.py文件:數據庫
import os DEBUG = True SECRET_KEY = os.urandom(24) DIALECT = 'mysql' DRIVER = 'mysqldb' USERNAME = 'root' PASSWORD = 'ROOT' HOST = '127.0.0.1' DATABASE = 'mytest' SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:@localhost:3306/mis_db?charset=utf8' SQLALCHEMY_TRACK_MODIFICATIONS = False
父模板html:flask
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>主頁 {% block logintitle %} {% endblock %} {% block registtitle %} {% endblock %} {% block questiontitle %} {% endblock %} {% block indextitle %} {% endblock %} {% block detailtitle %} {% endblock %} {% block selfinfotitle %} {% endblock %} {% block usertitle %} {% endblock %} </title> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/myweb.css') }}"> <script src="{{ url_for('static',filename='js/switch.js') }}"></script> <script src="{{ url_for('static',filename='js/footerPosition.js') }}"></script> {% block loginhead %} {% endblock %} {% block registhead %} {% endblock %} {% block questionhead %} {% endblock %} {% block indexhead %} {% endblock %} {% block detailhead %} {% endblock %} {% block selfinfohead %} {% endblock %} {% block userhead %} {% endblock %} </head> <body id="myBody" style="background-image: url(/static/img/bg.jpg)"> <main> <nav class="navbar navbar-default" role="navigation"> <div class="container-fluid"> <div class="navbar-header"> <a href="{{ url_for('index') }}" class="navbar-brand">首頁</a> <button type="submit" class="btn btn-default" style="margin-top: 12px"> <a href="{{ url_for('question') }}">發佈</a></button> <form class="navbar-form navbar-left" action="{{ url_for('search') }}" method="get"> <div class="form-group"> <input name="q" type="text" class="form-control" placeholder="請輸入關鍵字"> </div> <button type="submit" class="btn btn-default" style="margin-top: 3px">搜索</button> </form> </div> <ul class="nav navbar-nav navbar-right"> {% if susername %} <li><a href="{{ url_for('user',user_id =session.get('id'),tag = 1) }}">{{ susername }}</a></li> <li><a href="{{ url_for('logout') }}">註銷</a></li> {% else %} <li><a href="{{ url_for('regist') }}"><span class="glyphicon glyphicon-user"></span> 註冊</a></li> <li><a href="{{ url_for('login') }}"><span class="glyphicon glyphicon-log-in"></span> 登陸</a> </li> {% endif %} <li style="float: right"><img id="myOnOff" onclick="mySwitch()" src="http://www.runoob.com/images/pic_bulbon.gif" class="bulb"></li> </ul> </div> </nav> </main> <footer class="fixed-bottom">@版權全部</footer> </body> {% block loginbody %} {% endblock %}. {% block registbody %} {% endblock %} {% block questiontbody %} {% endblock %} {% block indexbody %} {% endblock %} {% block detailbody %} {% endblock %} {% block selfinfobody %} {% endblock %} {% block userbody %} {% endblock %} </html>
首頁html:bootstrap
{% extends'myweb.html' %} {% block indextitle %}首頁{% endblock %} {% block indexhead %} <link rel="stylesheet" type="text/css" href="../static/css/component.css"/> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <script src="../static/js/login.js"></script> {% endblock %} {% block indexbody %} <div class="container"> <div class="row clearfix"> <div class="col-md-10 column" id="rgba1"> <h3 align="center">旅遊問答區域</h3> <ul> {% for foo in question %} <li> <a href="{{ url_for('user',user_id = foo.author_id,tag = 1) }}">{{ foo.author.username }}</a> <br> <p>標題:<a href="{{ url_for('detail',question_id=foo.id) }}">{{ foo.title }}</a></p> <br> <p>內容:{{ foo.detail }}</p> <span>評論數: ({{ foo.comments|length }})</span> <span class="badge pull-right">{{ foo.create_time }}</span> <hr> </li> {% endfor %} </ul> </div> </div> </div> {% endblock %}
登陸頁面html:
{% extends'myweb.html' %} {% block logintitle %}登陸頁面{% endblock %} {% block loginhead %} <link rel="stylesheet" type="text/css" href="../static/css/component.css"/> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <script src="../static/js/login.js"></script> {% endblock %} {% block loginbody %} <div class="logo_box"> <h3 class="h3">請登陸</h3> <form action="{{ url_for('login') }}" method="post"> <div class="input_outer"> <span class="u_user"></span> <input id="uname" class="text" style="color: gold" type="text" placeholder="請輸入帳號" name="username"> </div> <div class="input_outer"> <span class="us_uer"></span> <input id="upass" class="text" style="color:black ; position:absolute; z-index:100;" value="" type="password" placeholder="請輸入密碼" name="password"> </div> <div class="errorText" id="error_box" style="color: black"><br></div> <div> <button onclick="return fnLogin()" class="lb1" style="color:black">登陸</button> </div> </form> </div> {% endblock %}
註冊頁面html:
{% extends'myweb.html' %} {% block registtitle %}註冊頁面{% endblock %} {% block registhead %} <link rel="stylesheet" type="text/css" href="../static/css/component.css"/> <script src="../static/js/regist.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> {% endblock %} {% block registbody %} <div class="logo_box"> <h3 class="h3">歡迎註冊</h3> <form action="{{ url_for('regist') }}" method="post"> <div class="input_outer"> <span class="u_user"></span> <input id="uname" class="text" style="color: gold" type="text" placeholder="請輸入帳號" name="username"> </div> <div class="input_outer"> <span class="u_user"></span> <input id="unickname" class="text" style="color: black" type="text" placeholder="請輸入暱稱" name="nickname"> </div> <div class="input_outer"> <span class="us_uer"></span> <input id="upass" class="text" style="color:black ; position:absolute; z-index:100;" value="" type="password" placeholder="請輸入密碼" name="password"> </div> <div class="input_outer"> <span class="us_uer"></span> <input id="upass1" class="text" style="color:black ; position:absolute; z-index:100;" value="" type="password" placeholder="請再次輸入密碼"> </div> <div class="errorText" id="error_box" style="color: red"><br></div> <div> <button class="lb1" style="color:black" type="submit" onclick="return fnRegist()">註冊</button> </div> </form> </div> {% endblock %}
發佈問答頁面html:
{% extends'myweb.html' %} {% block questiontitle %}問答頁面{% endblock %} {% block questionhead %} <link rel="stylesheet" type="text/css" href="../static/css/myweb.css"/> <link rel="stylesheet" type="text/css" href="../static/css/component.css"/> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> {% endblock %} {% block questiontbody %} <h3 class="h3">發佈問答</h3> <div class="ques"> <form action="{{ url_for('question') }}" method="post"> <div class="form-group"> <label for="questionTitle" style="color: black">標題</label><br> <textarea class="textareabg" rows="1" id="questionTitle" name="title" style="width: 700px"></textarea> <label for="questionDatail" style="color: black">詳情:</label><br> <textarea class="textareabg" rows="5" id="questionDatail" name="detail" style="width: 700px"></textarea> <br> <div id=""><br></div> <input type="submit" value="發佈" class="btn btn-default" onclick="" style="margin-left: 100%"> </div> </form> </div> {% endblock %}
問答詳情頁html:
{% extends 'myweb.html' %} {% block detailtitle %}問答詳情{% endblock %} {% block detailhead %} <link rel="stylesheet" type="text/css" href="../static/css/component.css"/> <script src="../static/js/regist.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> {% endblock %} {% block detailbody %} <div class="col-md-2 column "></div> <div class="col-md-8 column " id="rgba1"> <ul class="list-unstyled"> <li> <h2 href="#" class="text-center">{{ ques.title }}</h2> <br> <p class="text-center"> <a href="{{ url_for('user',user_id = session.get('id'),tag = 1) }}"> <small>{{ ques.author.username }}</small></a> </a>    <span class="pull-center"><small>{{ ques.create_time }}</small></span> </p> <p>{{ ques.detail }}</p> <form action="{{ url_for('comment') }}" method="post"> <div class="form-group"> <textarea name="new_comment" class="form-control" rows="5" id="comment" placeholder="請輸入評論"></textarea> <input type="hidden" name="question_id" value="{{ ques.id }}"> </div> <button type="submit" class="btn btn-default" style="margin-left:48% ">發送</button> </form> </li> </ul> <hr> <h4>評論:({{ ques.comments|length }})</h4> <ul class="list-unstyled"> {% for foo in ques.comments %} <li class="list-group-item"> <a href="{{ url_for('user',user_id = foo.author.id,tag = 1) }}">{{ foo.author.username }}</a> <span class="badge pull-right">{{ foo.create_time }}</span> <p>{{ foo.detail }}</p> <br> </li> {% endfor %} </ul> </div> <div class="col-md-2 column "></div> {% endblock %}
我的中心html:
{% extends'myweb.html' %} {% block usertitle %}我的中心{% endblock %} {% block userhead %} {% endblock %} {% block userbody %} <div class="container"> <div class="row clearfix"> <div class="col-md-2 column"> </div> <div class="col-md-8 column"> <ul class="nav nav-tabs"> <li> <a href="{{ url_for('user',user_id = user.id,tag = 1) }}">所有問答</a> </li> <li> <a href="{{ url_for('user',user_id = user.id,tag = 2) }}">所有評論</a> </li> <li> <a href="{{ url_for('user',user_id = user.id,tag = 3) }}">我的信息</a> </li> </ul> </div> <div class="col-md-2 column"> </div> </div> </div> {% block user %}{% endblock %} {% endblock %}
{% extends 'user.html' %} {% block user %} <div class="container"> <div class="row clearfix"> <div class="col-md-2 column"> </div> <div class="col-md-8 column" id="rgba1"> <p class="text-center"> <small>{{ username }}</small> </p> <hr> <h3 align="center"> <small>所有問答</small> </h3> <ul class="list-unstyled"> {% for foo in questions %} <li class="list-group-item"> <span class="glyphicon glyphicon-user"></span><a>{{ foo.author.username }}</a> <p>標題:{{ foo.title }}</p> <p>問答內容:{{ foo.detail }}</p> <span class="badge pull-right">{{ foo.create_time }}</span><br> <br> </li> {% endfor %} </ul> </div> <div class="col-md-2 column"> </div> </div> </div> {% endblock %}
{% extends 'user.html' %} {% block user %} <div class="container"> <div class="row clearfix"> <div class="col-md-2 column"> </div> <div class="col-md-8 column" id="rgba1"> <p class="text-center"><small>{{ username }}</small></p> <hr> <h3 align="center"> <small>所有評論</small> </h3> <ul class="list-unstyled"> {% for foo in comments %} <li class="list-group-item"> <span class="badge pull-right">{{ foo.create_time }}</span> <p>文章標題:{{ foo.question.title }}</p> <p>評論內容:{{ foo.detail }}</p> <span class="glyphicon glyphicon-user"></span><small ><a>{{ foo.author.username }}</a></small> <br> </li> {% endfor %} </ul> </div> <div class="col-md-2 column"> </div> </div> </div> {% endblock %}
{% extends 'user.html' %} {% block user %} <div class="container"> <div class="row clearfix"> <div class="col-md-2 column"> </div> <div class="col-md-8 column" id="rgba1"> <p class="text-center"> <small>{{ username }}</small> </p> <hr> <h3 align="center"> <small>我的信息</small> </h3> <ul class="list-group"> <li class="list-group-item" style="background-color: antiquewhite"><span class="glyphicon glyphicon-user"></span>用戶:{{ username }}</li> <li class="list-group-item" style="background-color: wheat">暱稱</li> <li class="list-group-item" style="background-color: aquamarine">文章篇數:{{ questions|length }}</li> </ul> </div> <div class="col-md-2 column"> </div> </div> </div> {% endblock %