期末做品檢查

1、我的學期總結javascript

   這學期剛開始接觸到python,python的簡潔,以及豐富的模塊,廣闊的應用領域吸引了我。學習python以來,以爲python仍是比較簡單,容易上手的,就基本語法而言,可是有些高級特性掌握起來仍是有些難度,須要時間去消化。python給我最大的印象就是語法簡潔,就像寫僞代碼同樣,不少其餘語言要用不少行才能實現的操做python可能幾行就搞定了,這讓人擺脫了繁雜的語法而專一於問題自己,這也正是我爲何不太喜歡Java的緣由之一,雖然它很強大。css

  剛開始學習不少疑惑,到底該如何學python,該從何下手?我回想了一下,根據本身的我的經驗,總結了一下。首先,學習一門語言,語言基礎很重要,咱們須要瞭解該語言的特性,以及全部的語法規則,關鍵詞等內容,因此,咱們須要先把python基礎過一遍,我建議去菜鳥教程去過一遍,這裏不是廣告,只是本人通常都在菜鳥官方看各類語言的編程入門。在基礎學習的過程當中,我建議快速的過一遍,把能理解的理解消化掉,比較難理解的不要浪費太多的時間去揣摩,由於有些語法或者特性在基礎學習中根本不能很好的展現,沒有實際操做單靠文字描述,是很難理解,死記硬背下來的東西不利於長期記憶和使用,因此快速瀏覽一遍,真正的學習放到後面的模塊學習和項目實戰,在模塊學習和實戰操做中能看到實實在在的執行效果,更利於理解。html

  總的來講,這個學期學習到了這麼有趣的網頁製做,不過如今本人的經驗仍是匱乏,只是學習到簡單的基礎知識,還應該繼續增強學習,讓本身的網頁佈局更加美化。在這裏還要感謝老師這一學期的指導,讓咱們瞭解到python的奧妙。前端

 

 

2、總結Python+Flask+MysqL的web建設技術過程java

  1. 所需工具: pycharm64.exe + Python 3.6 64-bit + MySQL + Navicat for MySQL 
  2. 在本身所在的項目建立py文件、 html文件、css文件、js文件,以下圖:

 

  (1)主py 文件所需庫python

from flask import Flask,render_template,request,redirect,url_for,session
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
from functools import wraps
import config
from sqlalchemy import or_
from werkzeug.security import generate_password_hash,check_password_hash

  

(2)建立數據庫mysql

A、數據庫鏈接,建立數據庫,配置連接數據庫信息,創建mysql和app的鏈接。web

    

import os

SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:@127.0.0.1:3306/mis_db?charset=utf8'
SQLALCHEMY_TRACK_MODIFICATIONS = False

SECRET_KEY = os.urandom(24)
app = Flask(__name__)
app.config.from_object(config)
db = SQLAlchemy(app)

 

B、建立用戶模型。sql

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(20))

    @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):
    __table__name = '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)
    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'))

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'))
    author = db.relationship('User', backref=db.backref('comments'))
#db.create_all()

 

C、經過用戶模型,學習對數據庫進行增刪改查操做。數據庫

#增
user = User(username='su0001',password='123456')
db.session.add(user)
db.session.commit()

#改
user=User.query.filter(User.username=='su0002').first()
user.password='1234567'
db.session.commit()
#刪
user=User.query.filter(User.username=='su0002').first()
db.session.delete(user)
db.session.commit()
#查
user=User.query.filter(User.username=='su0001').first()
print(user.id,user.password)

 #增、改                                  

                                  #刪、查

 

     

  D、實現密碼保護功能

 

(3)頁面設計

A、網站父模板統一佈局:頭部導航條、底部圖片導航、中間主顯示區域佈局

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}Title</title>
    <link rel="stylesheet"type="text/css"href="{{ url_for('static',filename='css/base.css') }}">
    <script src="{{ url_for('static',filename='js/base.js') }}"></script>
    <base target="_blank" />

    {% block head %}{% endblock %}
</head>
<body background="http://p0.so.qhimgs1.com/t01d2e82c8c8f2be36c.jpg" id="myBody">
    <nav class="nav">
        <ul>
            <li><a href="{{ url_for('index') }}"><img src="../static/images/img1.png">首頁</a></li>
            <li><a href=""><img src="../static/images/img2.png">下載</a></li>
            <li><a href="{{ url_for('question') }}"><img src="../static/images/img5.png">發佈問答</a></li>
            <div>
                {% if user %}
                    <li><a href="{{ url_for('userbase',user_id = session.get('userid'),tag = 1) }}"><img src="../static/images/img3.png">{{ session.get('user') }}</a></li>
                    <li><a href="{{ url_for('logout') }}"><img src="../static/images/img4.png">註銷</a></li>
                {% else %}
                    <li><a href="{{ url_for('login') }}"><img src="../static/images/img3.png">登陸</a></li>
                    <li><a href="{{ url_for('regist') }}"><img src="../static/images/img4.png">註冊</a></li>
                {% endif %}
             </div>
            <form action="{{ url_for('search') }}" method="get" class="navbar-form navbar-left">
            <img class="on_off" id="on_off" onclick="mySwitch()" src="../static/images/pic_bulbon.gif" width="50px">
            <button style="float: right;margin: 5px auto;border-radius: 5px;height: 26px" type="submit"><span class="glyphicon glyphicon-search" aria-hidden="true"></span>搜索</button>
            <input style="float: right;margin: 5px auto;border-radius: 8px;width: 200px;height: 20px;" type="text"name="q" placeholder="輸入請關鍵字">
             </form>

        </ul>
    </nav>

<div id="bottom">
    <a href="">關於咱們</a>
    <a href="">意見反饋</a>
    <a href="">安全保障</a>
</div>

<div class="copyright">
    <p>Copyright © 2017. Created by <a href="#" target="_blank">suxihong</a></p>
</div>

{% block main %}{% endblock %}
</body>
</html>

  夜間模式的開啓與關閉。定義script開關切換函數,用onclick函數進行調用。

     

 

B、註冊、登陸、註銷py文件:

  註冊界面完成註冊功能。在主py文件定義函數,獲取form中的數據且判斷用戶名是否存在:存在報錯,若不存在則存進數據庫中,redirect重定向到登陸頁。

  登陸界面。完成登陸功能:與註冊同樣完成js文件,在主py文件定義函數,讀取表單數據查詢數據庫。當用戶名密碼正確時,記住用戶名並跳轉到首頁;當用戶名密碼不正確時,提示相應錯誤。同時,用session記住用戶名。

#登陸函數
@app.route('/login/',methods=['GET','POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    else:
        username = request.form.get('username')
        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 'password error'
        else:
            return 'username error'

#註冊函數
@app.route('/regist/',methods=['GET','POST'])
def regist():
    if request.method == 'GET':
        return render_template('regist.html')
    else:
        username = request.form.get('username')
        nickname = request.form.get('nickname')
        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,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'))

# 行動前須要登陸,定義裝飾器
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

  定義JavaScript 函數,設置登陸註冊頁面驗證用戶名與登陸密碼6-20位,註冊還需包括驗證用戶名首字母不能是數字,只能包含字母和數字,輸入的兩次密碼必須一致,並在各自html頁面的button標籤onclick調用這個函數。實現js文件,onclick函數return True時才提交表單,return False時不提交表單。

1)regist.html

{% extends 'base.html' %}
{% block title %}Regist{% endblock %}

{% block head %}
    <link href="{{ url_for('static',filename='css/js31.css') }}" rel="stylesheet" type="text/css">
    <script src="{{ url_for('static',filename='js/regist.js') }}"></script>
{% endblock %}

{% block main %}
    <div class="box">
            <h2>註冊頁面</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="unickname" type="text" placeholder="暱稱" name="nickname">
        </div>
             <div class="input_box">
                 輸入密碼: <input id="upass" type="password" placeholder="請輸入密碼" name="password"></div>
                <div class="input_box">
                確認密碼: <input id="checkpass" type="password" placeholder="請確認密碼">
             </div>
        <div id="error_box"><br></div>
        <div class="input_box">
            <button onclick="fnRegist()">註冊</button>
            <button onclick=window.alert("此頁面詢問您是否要離開:您輸入的數據可能不會被保存")>取消</button></div>
            </form>
    </div>
{% endblock %}

  rejist.js

function fnRegist() {
    var oPass=document.getElementById("upass").value;
    var oPass1=document.getElementById("checkpass").value;

    if(oPass!=oPass1){
        document.getElementById("error_box").innerHTML="兩次密碼不一致!";
        return false;
    }
    return true;
}

  

2)login.html

{% extends 'base.html' %}
{% block title %}歡迎您的登陸{% endblock %}

{% block head %}
    <link href="{{ url_for('static',filename='css/js31.css') }}" rel="stylesheet" type="text/css">
    <script src="{{ url_for('static',filename='js/login.js') }}"></script>
{% endblock %}

{% block main %}
    <div class="box">
            <h2>登陸頁面</h2>
            <form action="{{ url_for('login') }}" method="post">
            <div class="input_box">
               用戶名: <input id="uname" name="username" type="text" placeholder="請輸入用戶名">
        </div>
             <div class="input_box">
                密碼: <input id="upass" name="password" type="password" placeholder="請輸入密碼">
             </div>
        <div id="error_box"><br></div>
        <div class="input_box">
            <button onclick="return fnLogin()">登陸</button>
            <button onclick=window.alert("此頁面詢問您是否要離開:您輸入的數據可能不會被保存")>取消</button></div>
            </form>
    </div>
{% endblock %}

  

   login.js

function fnLogin() {
    var oUname=document.getElementById("uname");
    var oUpass=document.getElementById("upass");
    var oError=document.getElementById("error_box");
    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 = "只能包含字母或數字。";
                isNotError = false;
                return isError;
            }
        }
    }
    if (oUpass.value.length<6||oUpass.value.length>20){
        oError.innerHTML="密碼的長度:6-20位";
        isError=false;
        return isError;
    }
    return isError;

}

  

  

  實現登陸後更新導航:用上下文處理器app_context_processor定義函數,獲取session中保存的值,返回字典。在父模板中更新導航,插入登陸狀態判斷代碼。注意用{% ... %}表示指令、{{ }}表示變量。完成註銷功能:清除session並進行跳轉頁面。

@app.context_processor
def mycontext():
    user = session.get('user')
    if user:
        return {'user': user}
    else:
        return {}

        

 

C、發佈、列表顯示

  1)發佈問答界面、編寫要求登陸的裝飾器,定義函數將其返回。應用裝飾器,要求在發佈前進行登陸,登陸後可發佈。創建發佈內容的對象關係映射,完成發佈函數。

@app.route('/question/',methods=['GET','POST'])
@loginFirst   # 把loginFirst放在要登陸才能進入的界面中
def question():
    if request.method == 'GET':
        return render_template('question.html')
    else:
        title = request.form.get('title')
        detail = request.form.get('detail')
        user = User.query.filter(User.username == session.get('user')).first()
        author_id = user.id
        question = Question.query.filter(Question.title == title).first()
        if question:
            return 'question existed.'
        else:
            question = Question(title=title, detail=detail, author_id=author_id)
            question.author = user
            db.session.add(question)    # 數據庫,添加操做
            db.session.commit()
            return redirect(url_for('index'))

  

  question.html

{% extends 'base.html' %}
{% block title %}發佈問答{% endblock %}

{% block head %}
    <link rel="stylesheet" href="{{ url_for('static',filename='css/question.css')}}">
{% endblock %}

{% block main %}
    <div class="question">
    <p class="name">歡迎你,{{ user }}</p>
    <h3>發佈問答</h3>
    <form class="box" action="{{ url_for('question') }}" method="post" >
        <div class="form-group">
            <label for="questionTitle">標題</label>
            <input type="text" name="title" class="form-control" id="questionTitle" placeholder="輸入標題">
        </div>

        <div class="form-group">
            <label for="questionDetail">詳情</label>
            <textarea name="detail" class="form-control" rows="5" id="questionDetail" placeholder="輸入內容"></textarea>
        </div>

        <div class="checkbox">
            <label>
                <input type="checkbox">Check me out
            </label>
        </div>
        <button type="submit" class="btn-default">發佈</button>
    </form>
     </div>
{% endblock %}

 

  

 

   2)在首頁添加顯示問答的列表,並定義好相應的CSS樣式。首頁列表顯示所有問答:將數據庫查詢結果傳遞到前端頁面,前端頁面循環顯示整個列表,進行問答排序。

@app.route('/')
def index():
    context = {
          'question': Question.query.order_by('-creat_time').all()
    }
    return render_template('index.html',**context)

  index.html

{% extends 'base.html' %}
{% block title %}首頁{% endblock %}

{% block head %}
    <link rel="stylesheet" href="{{ url_for('static',filename='css/index.css')}}" type="text/css">
{% endblock %}

{% block main %}
    <p>{{ user }}歡迎您來到首頁!</p>

    <div class="list-container">
        <div id="content">
        <ul class="note-list" style="list-style: none">
            {% for foo in question %}
                <li class="note-list-item">
                    <span class="glyphion glyphion-leaf" aria-hidden="true"></span>
                    <a href="{{ url_for('detail',question_id = foo.id)}}">{{ foo.title }}</a>
                    <p style="width: 450px;"> 詳情 {{ foo.detail }}</p>
                    <span class="glyphion glyphion-user" aria-hidden="true"></span>
                    <a href="{{ url_for('userbase',user_id = foo.author_id,tag = 1)}}">{{ foo.author.username }} 評論:({{ foo.comments|length }})</a>

                    <span class="badge">{{ foo.creat_time }}</span>

                </li>
            {% endfor %}
        </ul>
    </div>
</div>
{% endblock %}

 

  3)主PY文件寫視圖函數,帶id參數。 首頁標題的標籤作帶參數的連接,在詳情頁將數據的顯示在恰當的位置。創建評論的對象關係映射,嘗試實現發佈評論。 

    完成評論功能:定義評論的視圖函數,讀取前端頁面數據,保存到數據庫中 ,顯示評論次數,要求評論前登陸(調用登陸裝飾器),嘗試實現詳情頁面下的評論列表顯示。

@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   #把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))

 

  detail.html

{% extends 'base.html' %}
{% block title %}問答詳情{% endblock %}

{% block head %}
<link rel="stylesheet" href="{{ url_for('static',filename='css/detail.css')}}">
{% endblock %}

{% block main %}
    <div class="detail">
        <h3 >{{ ques.title }}  <small>{{ ques.author.username }}
            <span class="badge">{{ ques.creat_time }}</span>
            </small>
        </h3>

        <p class="lead" >詳情 {{ ques.detail }}</p>
    <hr>

    <form action="{{ url_for('comment') }}" method="post" class="box">
    <div class="form-group">
        <textarea name="new_comment" class="form-control" rows="5" id="new_comment" placeholder="write your comment"></textarea>
        <input name="question_id" type="hidden" value="{{ ques.id }}" />
    </div>
    <button type="submit" class="btn-default">發送</button>
     <br>

     <hr>
    <div class="form-group">
        <h4>評論:({{ ques.comments|length }})</h4>

        <ul class="list-group" style="list-style: none">
            {% for foo in ques.comments %}
                <li class="list-group-item">
                    <span class="glyphion glyphion-heart-empty" aria-hidden="true"></span>
                    <a href="{{ url_for('userbase',user_id = foo.author.id,tag = 1)}}">{{ foo.author.username }}</a>
                    <span class="badge">{{ foo.creat_time }}</span>
                    <p style="width: 450px;"> 詳情 {{ foo.detail }}</p>

                </li>
            {% endfor %}
        </ul>
    </div>
    </form>
    </div>



{% endblock %}

 

 

D、我的中心:實現評論列表顯示及排序。完成我的中心:我的中心的頁面佈局(html文件及相應的樣式文件),定義視圖函數向前端頁面傳遞參數,頁面顯示相應數據:發佈的所有問答、發佈的所有評論、我的信息;各個頁面連接到我的中心。

  實現標籤頁導航:利用嵌套繼承,製做我的中心的三個子頁面,重寫userbase.html中定義的user塊,分別用於顯示問答、評論、我的信息。我的中心—視圖函數、導航標籤與HTML頁面連接增長tag參數。

@app.route('/userbase/<user_id>/<tag>')
@loginFirst
def userbase(user_id,tag):
    user = User.query.filter(User.id == user_id).first()
    mycontext = {
        'user': user,
        #'user_name': user.username,
        #'questions': user.question,
        #'comments': user.comments
    }
    if tag == '1':
        return render_template('user1.html', **mycontext)
    elif tag == '2':
        return render_template('user2.html', **mycontext)
    else:
        return render_template('user3.html', **mycontext)

  

userbase.html

{% extends 'base.html' %}
{% block title %}我的中心{% endblock %}
{% block head %}
<link rel="stylesheet" href="{{ url_for('static',filename='css/index.css')}}">
{% endblock %}

{% block main %}
    <div id="content">
        <ul class="nav_ul" style="list-style:none;float:left">
            <li role="presentation"><a href="{{ url_for('userbase',user_id = user.id,tag = '1') }}">所有問答</a></li>
            <li role="presentation"><a href="{{ url_for('userbase',user_id = user.id,tag = '2') }}">所有評論</a></li>
            <li role="presentation"><a href="{{ url_for('userbase',user_id = user.id,tag = '3') }}">我的信息</a></li>
    </ul>
    </div>
    {% block user %}{% endblock %}
{% endblock %}

 

use1.html

{% extends 'userbase.html' %}
{% block title %}所有問答{% endblock %}
{% block head %}
<link rel="stylesheet" href="{{ url_for('static',filename='css/index.css')}}">
{% endblock %}
{% block user %}
  <div class="list-container">
        <ul class="note-list" style="list-style: none">
        {% for foo in user.question %}
            <li class="note-list-item">
                <span class="glyphion glyphion-leaf" aria-hidden="true"></span>
                <a href="{{ url_for('detail',question_id = foo.id)}}">{{ foo.title }}</a>
                <p style="font-family: 幼圓;color: black;"> 詳情 {{ foo.detail }}</p>
                <span class="glyphion glyphion-user" aria-hidden="true"></span>
                <a href="{{ url_for('userbase',user_id = foo.author_id,tag = 1)}}">{{ foo.author.username }}</a>

                <span class="badge">{{ foo.creat_time }}</span>

            </li>
        {% endfor %}
    </ul>
  </div>
{% endblock %}

 

user2.html

{% extends 'userbase.html' %}
{% block title %}所有評論{% endblock %}
{% block head %}
<link rel="stylesheet" href="{{ url_for('static',filename='css/index.css')}}">
{% endblock %}
{% block user %}
    <div class="list-container">
        <h3 style="font-family:幼圓 ;color:black;width:100px"><span class="glyphion glyphion-user" aria-hidden="true"></span>{{ username }}
            <br><small>所有評論 <span class="badge"></span></small>
        </h3>
        <ul class="list-group" style="margin: 10px;list-style: none">
            {% for foo in user.comments %}
            <li class="note-list-item">
                <span class="glyphion glyphion-haert-empty" aria-hidden="true"></span>
                <a href="#">{{ foo.author.username }}</a>
                <span class="badge">{{ foo.creat_time }}</span>

                <p style="font-family: 幼圓;color: black;"> 詳情 {{ foo.detail }}</p>
            </li>
        {% endfor %}
        </ul>
    </div>
{% endblock %}

 

user3.html

{% extends 'userbase.html' %}
{% block title %}我的信息{% endblock %}
{% block head %}
<link rel="stylesheet" href="{{ url_for('static',filename='css/index.css')}}">
{% endblock %}
{% block user %}
    <div class="list-container">
        <h3><span class="glyphion glyphion-user" aria-hidden="true"></span>{{ username }}
            <br><small>我的信息 <span class="badge"></span></small>
        </h3>
        <ul class="list-group" style="margin: 10px;list-style: nonefont-family: 幼圓;color:black;">
            <li class="list-group-item">用戶:{{ user.username}}</li>
            <li class="list-group-item">編號:{{ user.id }}</li>
            <li class="list-group-item">暱稱:{{ user.nickname}}</li>
            <li class="list-group-item">文章篇數:{{ user.question|length }}</li>
            <li class="list-group-item">評論數:{{ user.comments|length }}</li>
        </ul>
    </div>
{% endblock %}

 

 

 

 E、搜索,條件組合搜索:實現搜索功能:準備視圖函數search(),修改父模版中搜索輸入框所在的;完成視圖函數獲取搜索關鍵字,條件查詢並加載查詢結果,實現組合條件查詢

@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('index.html',question = ques)

    

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息