一、我的學期總結css
經過這一個學期的Python學習,我已經從簡單的簡單輸入輸出交互,畫一組同心圓以及詞頻統計再到HTML練習使用標籤製做簡單的頁面。 最後通過一步步的學習與研究,到如今已經可以作css樣式、JavaScript、HTML、Python去作一個簡單相似於簡書的能夠發佈簡單的問答、評論、登陸、註冊以及我的中心的做品。html
二、總結Python+Flask+MysqL的web建設技術過程,標準以下:python
1、開發工具:主要工具備:pycharm64.exe + Python 3.6 64-bit + MySQL + Navicat for MySQL(輔助工具)mysql
2、功能設計:web
一、登陸註冊:sql
利用CSS樣式以及和html,python數據庫
註冊須要用戶名,用戶密碼以及電話號碼:flask
用js進行註冊驗證,用戶名首字母不能爲數字,且必須爲6到20位,電話號碼必須爲11位,初始密碼與確認密碼必須一致且在6到20位之間。session
js代碼以下:app
function myRegister() { var oUname = document.getElementById("uname"); var oError = document.getElementById("error_box"); var oUpass = document.getElementById("upass"); var oConfirm = document.getElementById("uconfirmrpass"); var oUtel = document.getElementById("utel"); // var isError = true; oError.innerHTML = "<br>"; // oError.innerHTML="<br>" if ((oUname.value.length < 6) || (oUname.value.length > 20)) { oError.innerHTML = "用戶名必須爲6-20位"; return false; } else if ((oUname.value.charCodeAt(0) >= 48) && (oUname.value.charCodeAt(0) <= 57)) { oError.innerHTML = "用戶名首位必須爲字母"; 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 = "用戶名必須爲字母或數字"; return false; } } if (oUtel.value.length != 11) { oError.innerHTML = "電話號碼必須爲11位"; return false; } else for (var i = 0; i < oUname.value.length; i++) { if (oUtel.value.charCodeAt(i) < 48 || oUtel.value.charCodeAt(i) > 57) { oError.innerHTML = "電話號碼必須爲數字"; return false; } } if ((oUpass.value.length < 6) || (oUpass.value.length > 20)) { oError.innerHTML = "密碼必須6-20位"; return false; } else if (oConfirm.value != oUpass.value) { oError.innerHTML = "兩次輸入的密碼不一致"; return false; } return true; // window.alert("註冊成功") }
註冊HTML:
<form action="{{ url_for('register') }}" method="post"> <div class="container"> <div class="box"> <a href="{{ url_for('login') }}" class="active">登陸</a> <a>*</a> <a href="{{ url_for('register') }}">註冊</a> </div> <br><br> <div class="input_box"> Username:<input id="uname" type="text" placeholder="你的暱稱" name="Username"><br><br> Telphone:<input id="utel" type="text" placeholder="手機號" name="Telphone"><br><br> Password:<input id="upass" type="password" placeholder="設置密碼" name="Password"><br><br> Confirmpass:<input id="uconfirmrpass" type="password" placeholder="確認密碼" name="Confirmpass"><br><br></div> <div id="error_box"></div> <div> <button id="register" type="submit" onclick=" return myRegister()">註冊</button> </div> </div> </form>
註冊頁面功能實現:
登陸實現:
登陸須要根據用戶名,根據輸入的密碼查詢與數據庫的是否相同
js驗證:
function myLogin() { var oUname = document.getElementById("uname"); var oError = document.getElementById("error_box"); var oUpass = document.getElementById("upass"); var isError = true; oError.innerHTML = "<br>"; if ((oUname.value.length < 6) || (oUname.value.length > 20)) { oError.innerHTML = "用戶名必須爲6-20位"; isError = false; return isError; } else if ((oUname.value.charCodeAt(0) >= 48) && (oUname.value.charCodeAt(0) <= 57)) { oError.innerHTML = "用戶名首位必須爲字母"; isError = false; return isError; } 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 = "用戶名必須爲字母或數字"; isError = false; return isError; } } if ((oUpass.value.length < 6) || (oUpass.value.length > 20)) { oError.innerHTML = "密碼必須6-20位"; isError = false; return isError; } return isError; //return window.alert("登陸成功") }
登陸成功以後將會跳到首頁。
2、導航框
導航框的實現是在base.html,這樣其餘頁面只須要繼承這個父模板,就能夠用到導航框的內容。
下面是導航框的頁面,登陸成功以後,就能夠在右側看到登陸名以及註銷,點擊註銷將能夠跳到登陸頁面,從新登陸。
HTML:
<body id="myBody"> <nav class="daohang"> <div class="daohang_box"> <form action="{{ url_for('search')}}" method="get" > <a class="shouye" href="{{ url_for('index') }}">首頁</a> <input id="search_box" type="text" name="q" placeholder="請輸入關鍵詞查找"> <button id="search" type="submit">搜索</button> <a class="xiaoqu3" href="{{ url_for('question') }}">發佈影評</a> <img id="on_off" onclick="mySwitch()" src="{{ url_for('static',filename='images/bulbon.png') }}" > {% if Username %} {# <a class="xiaoqu1" href="{{ url_for('usercenter',user_id=session.get('id')}}">歡迎您{{session.get('Username'}}</a>#導航條的用戶#} <a class="xiaoqu1" href="{{ url_for('usercenter',user_id=session.get('userid') ,tag='1')}}">歡迎您{{session.get('user')}}</a>#導航條的用戶 {# <a class="xiaoqu1" href="#">歡迎您{{Username}}</a>#} <a class="xiaoqu2" href="{{ url_for('logout') }}">註銷</a> {% else %} <a class="xiaoqu1" href="{{ url_for('login') }}">登陸</a> <a class="xiaoqu2" href="{{ url_for('register') }}">註冊</a> {% endif %}</form> </div> </nav>
3、發佈功能:
發佈問答,首先要登陸才能發佈
用了一個登陸裝飾器,判斷用戶是否登陸:
def login_re(func): @wraps(func) def wrapper(*args, **kwargs): if session.get('user'): return func(*args, **kwargs) else: return redirect(url_for('login')) return wrapper
在發佈影評的主py里加入
@login_re
便可判斷是否登陸了。
question的HTML代碼:
{% extends 'base.html' %} {% block title %}發佈影評{% endblock %} {% block head %} <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/question.css') }}"> {% endblock %} {% block main %} <div class="fa"> <h1>發佈影評</h1> <form action="{{ url_for('question') }}" method="post"> <div class="zhuti"> <label for="question">標題</label><br> <input id="question" type="text" name="title"></div><br> <div class="fa-question"> <label for="questionDetial">詳情</label><br> <textarea id="questionDetial" rows="12" name="detail"></textarea></div> <div class="check"><input type="checkbox">check me out</div> <button class="sumbit" type="submit">提交</button> </form> </div> {% endblock %}
4、用戶評論:
同一個問答要保證不一樣用戶的評論顯示在相同問答下面:
<form action="{{ url_for('comment') }}" method="post"> <div class="ping"> <div class="pinglun"><label for="comment">評論:({{ ques.comments|length }})</label><br></div> <textarea id="comment" rows="8" name="commentdetail" PLACEHOLDER="寫下你的評論"></textarea> <input name="question_id" type="hidden" value="{{ ques.id }}"/> <div class="but"> <button type="submit" class="fasong">發送評論</button> </div> </div> </form>
顯示評論列表:
<ul> {% for foo in ques.comments %} <li> <img id="tubiao" src="{{ url_for('static',filename='images/tou.jpg') }}"> <a href="{{ url_for('usercenter',user_id=foo.author_id,tag=1 )}}">{{ foo.author.Username }}</a> <a class="creat_time">{{ foo.creat_time }}</a> <a class="title" href="{{ url_for('detail',question_id=foo.id) }}">{{ foo.title }}</a> <p class="abstract">{{ foo.detail }}</p> </li> {% endfor %}</ul>
5、查看我的中心
我的中心模板:
{# 新頁面user.html,用<ul ><li role="presentation"> 實現標籤頁導航。#} {% extends 'base.html' %} {% block title %}我的中心{% endblock %} {% block head %} <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/userbase.css') }}"> {% endblock %} {% block main %} <div class="nav1"> <ul> <li role="presentation"><a href="{{ url_for('usercenter',user_id=user.id ,tag='1')}}">所有影評</a></li> <li role="presentation"><a href="{{ url_for('usercenter',user_id=user.id ,tag='2')}}">所有評論</a></li> <li role="presentation"><a href="{{ url_for('usercenter',user_id=user.id ,tag='3')}}">我的資料</a></li> </ul> </div><br><br><br> {% block user %}{% endblock %} {% endblock %}
所有影評:
{% extends 'userbase.html' %} {% block head %} <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/userbase.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/user.css') }}"> {% endblock %} {% block user %} <div class="juli"> <h3>{{ user.Username}}<br> <small>所有影評</small> </h3> </div> <div class="xiao_ul"> <ul> {% for foo in user.question %} <li> <img id="tubiao" src="{{ url_for('static',filename='images/pl.jpg') }}"> <a href="#">{{ foo.author.Username }}</a> <a class="creat_time">{{ foo.creat_time }}</a><br> {# <p class="title" href="#" onclick="window.location.replace({{ url_for('detail')}})">{{ foo.title }}</p>#} <a class="title" href="{{ url_for('detail',question_id=foo.id)}}">{{ foo.title }}</a> <div class="abstract">{{ foo.detail }}</div> </li> {% endfor %}</ul> </div> {% endblock %}
所有資料:
{% extends 'userbase.html' %} {% block user %} {% block head %} <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/userbase.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/user.css') }}"> {% endblock %} <div class="juli"> <h3>{{ user.Username }}<br> <small>我的資料</small> </h3> </div> <div class="xiao_ul"> <ul> <li>頭像:<img id="tubiao" src="{{ url_for('static',filename='images/tou.jpg') }}"></li> <li>用戶:{{ user.Username }}</li> <li>文章篇數:{{ user.question|length }}</li> <li>評論數:{{ user.comments|length }}</li> </ul> </div> {% endblock %}
6、模型分離與遷移
裝飾器分離:
from flask import Flask, render_template, request, redirect, url_for, session from functools import wraps def login_re(func): @wraps(func) def wrapper(*args, **kwargs): if session.get('user'): return func(*args, **kwargs) else: return redirect(url_for('login')) return wrapper
exit.py
from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy()
數據的遷移:
from flask_script import Manager from flask_migrate import Migrate,MigrateCommand from denglu import app from exts import db from models import Question,User,Comment manger=Manager(app) migrate=Migrate(app,db) manger.add_command('db',MigrateCommand) if __name__ == '__main__': manger.run()#使用Manager實例
表遷移:
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(20), nullable=False) _Password=db.Column(db.String(200), nullable=False)#內部使用 Telphone = db.Column(db.String(20), nullable=True) @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(100), nullable=False) detail = db.Column(db.Text, nullable=False) creat_time = db.Column(db.DateTime, default=datetime.now) 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'))#外鍵 detail = db.Column(db.Text, nullable=False) creat_time = db.Column(db.DateTime, default=datetime.now) question=db.relationship('Question',backref=db.backref('comments',order_by=creat_time.desc))# author = db.relationship('User', backref=db.backref('comments')) # db.create_all()
鏈接數據庫:
import os #DEBUG=True SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:@127.0.0.1:3306/login_db?charset=utf8' SQLALCHEMY_TRACK_MODIFICATIONS = False SECRET_KEY = os.urandom(24)