管理信息系統 課程設計


 

一、項目選擇

  1. 繼續沿用Python+Flask+MysqL的web建設技術,開發一個網站
  2. 網站主題根據個人興趣與特長自由選擇
  3. 此項目屬於個人項目,每個同學獨立完成,和其他同學不一樣 

二、項目要求

    1. 整個網站風格統一,布局合理,盡量美觀。
    2. 作品必須完成:
      1. 網站父模板統一布局:頭部導航條、底部圖片導航、中間主顯示區域布局
      2. 注冊、登錄、注銷
      3. 發布、列表顯示
      4. 詳情頁
      5. 評論、列表顯示
      6. 個人中心
      7. 搜索,條件組合搜索
      8. 文章分類、顯示
      9. 點贊、收藏
      10. 修改密碼、頭像、上傳頭像
      11. 我的發布、點贊、收藏、評論
      12. 高級搜索
      13. 熱門文章、推薦文章
    3.  參考網站:http://bbs.xiaomi.cn/

A.系統概要說明

這個網站我做的是有關文學論壇的系統,基於Python+Flask+MysqL的web建設技術,在上學期學習的基礎上進行完善,雖然不算完美,但是對Python有了更進一步的了解,做起來更得心應手。

Python優點:

1.“優雅”、“明確”、“簡單”

      這是python的定位,使得python程序看上去簡單易懂,初學者容易入門,學習成本更低。但隨着學習的不但深入,python一樣可以滿足勝任復雜場景的開發需求。引用一個說法,Python的哲學是就是簡單優雅,盡量寫容易看明白的代碼,盡量寫少的代碼。

2.  開發效率高

     python作為一種高級語言,具有豐富的第三方庫,官方庫中也有相應的功能模塊支持,覆蓋了網絡、文件、GUI、數據庫、文本等大量內容。因此開發者無需事必躬親,遇到主流的功能需求時可以直接調用,在基礎庫的基礎上施展拳腳,可以節省你很多功力和時間成本,大大降低開發周期。

3.  無需關注底層細節

     Python作為一種高級開發語言,在編程時無需關注底層細節(如內存管理等)。

4.  功能強大

     Python是一種前端后端通吃的綜合性語言,功能強大,php能勝任的角色它都能做,至於后端如何勝任,需要在后續學習中逐步領悟。

5.  可移植性

     Python可以在多種主流的平台上運行,開發程序時只要繞開對系統平台的依賴性,則可以在無需修改的前提下運行在多種系統平台上,具體有待后續學習中深入展開。其他優點有待繼續發掘。

  Python缺點:

1. 代碼運行速度慢

    因為Python是一種高級開發語言,不像c語言一樣可以深入底層硬件最大程度上挖掘榨取硬件的性能,因此它的運行速度要遠遠慢於c語言。另外一個原因是,Python是解釋型語言,你的代碼在執行時會一行一行地翻譯成CPU能理解的機器碼,這個翻譯過程非常耗時,所以很慢。而C程序是運行前直接編譯成CPU能執行的機器碼,所以非常快。

    但需要注意的是,這種慢對於不需要追求硬件高性能的應用場合來講根本不是問題,因為它們比較的數量級根本不是用戶能直觀感受到的!想想程序執行所需的時間數量級?例如開發一個下載MP3的網絡應用程序,C程序的運行時間需要0.001秒,而Python程序的運行時間需要0.1秒,慢了100倍,但由於網絡更慢,需要等待1秒,用戶體驗幾乎沒有差別,除非你用非常精確的計時器來計時。

2.  發布程序時必須公開源代碼

     什么?有沒有搞錯?是的,發布程序時我們必須公開源代碼!還是因為Python是一種解釋性語言,沒有編譯打包的過程(據說最新的python可以打包,但本質上還是把源代碼和解釋器打在一起,沒有太大實際意義)。想想我們的shell腳本是不是也是這個情況,你能在不發布源代碼的情況下發布一個黑盒子程序來讓別人正常使用么?

     這個缺點僅限於你想單純靠賣開發出來的軟件產品掙錢的時候。但在這個開發互聯的時代,不靠賣產品本身來賺錢的商業模式越來越主流了,所以問題也不是沒法解決。 

B.網站結構設計

網站的結構設計是體現內容設計與創意設計的關鍵環節,在內容設計完成之后,網站的目標及內容主題等有關問題已經確定。結構設計要做的事情就是如何將內容划分為清晰合理的層次體系,比如欄目的划分及其關系、網頁的層次及其關系、鏈接的路徑設置、功能在網頁上的分配等等,以上這些都僅僅是前台結構設計,而前台結構設計的實現需要強大的后台支撐,后台也應有良好的結構設計以保證前台結構設計的實現。在我看來,根據開發量來說,Flask小巧簡單易上手,同時具有強大的擴展能力,使其功能可以不弱於django、Tornado等框架,我最終選擇了Flask。從 建表設計 到  瀏覽器前端展示 整體的結構,后台連接數據庫,整體布局是否美觀,都是從網站結構分析這方面出發要考慮的問題.

C.模塊詳細設計

模塊詳細設計這一方面,我是從

  1. 網站父模板統一布局:頭部導航條、底部圖片導航、中間主顯示區域布局
  2. 注冊、登錄、注銷
  3. 發布、列表顯示
  4. 詳情頁
  5. 評論、列表顯示
  6. 個人中心
  7. 搜索,條件組合搜索
  8. 文章分類、顯示
  9. 點贊、收藏
  10. 修改密碼、頭像、上傳頭像
  11. 我的發布、點贊、收藏、評論
  12. 高級搜索
  13. 熱門文章、推薦文章

這幾方面來規划我的整個網站的,以及考慮實現功能所需的類及具體的方法函數,包括涉及到的sql語句、Python+Flask+MysqL的web建設技術等。

D.數據庫設計

一直以來,在數據庫庫方面我掌握的不是很好,有些細節的東西我會不小心忽略。但在這一次大作業設計中,感覺自己能力有所提高,對數據庫也有了更進一步的掌握。

數據庫設計的設計內容包括:需求分析、概念結構設計、邏輯結構設計、物理結構設計、數據庫的實施和數據庫的運行和維護。

數據庫設計是指對於一個給定的應用環境,構造最優的數據庫模式,建立數據庫及其應用系統,使之能夠有效地存儲數據,滿足各種用戶的應用需求(信息要求和處理要求)。在數據庫領域內,常常把使用數據庫的各類系統統稱為數據庫應用系統

我們要搭建后台,與MySQL相連接,可能是由於我電腦的問題,MySQL經常自動關閉,這個時候要打開電腦的管理,去服務那里設置為自動。有時候百度能解決很多問題。

連接數據庫前,要先確認以下事項:

  • 已經創建了數據庫 TESTDB.
  • 在TESTDB數據庫中您已經創建了表 EMPLOYEE
  • EMPLOYEE表字段為 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME。
  • 連接數據庫TESTDB使用的用戶名為 "testuser" ,密碼為 "test123",你可以可以自己設定或者直接使用root用戶名及其密碼,Mysql數據庫用戶授權請使用Grant命令。
  • 在你的機子上已經安裝了 Python MySQLdb 模塊。

再者,數據庫要明確步驟,需求分析、概念設計、邏輯設計、物理設計、驗證設計和運行維護設計,這些都缺一不可。

from flask import Flask
from exts import db #數據庫使用方法
import config #數據庫連接文件
from apps.front import bp as front_bp #連接前端數據文件

E.系統實現的關鍵算法與數據結構

def create_app():
app = Flask(__name__)
app.config.from_object(config)
app.register_blueprint(front_bp)
db.init_app(app)

return app


if __name__ == '__main__':
app = create_app()
app.run(port=8000)
#點贊功能
@bp.route('/dianzan/',methods=['GET','POST'])
@login_required
def dianzan():
user_id=g.front_user.id
post_id=request.form.get('post_id')
dianzan=DianzanModel(user_id=user_id,post_id=post_id)
db.session.add(dianzan)
db.session.commit()
return redirect(url_for('front.post_detail',post_id=post_id))

#用戶上傳頭像
@bp.route('/avatar/<user_id>',methods=['POST'])
@login_required
def updata_acatar(user_id):
user = FrontUser.query.filter(FrontUser.id == user_id).first()
f = request.files['img']
basepath = os.path.dirname(__file__) # 當前文件所在路徑
upload_path = os.path.join('F:/godlike/static/img', f.filename) # 注意:沒有的文件夾一定要先創建,不然會提示沒有該路徑
f.save(upload_path)
user.avatar = 'img/' + f.filename
db.session.commit()
return redirect(url_for('front.usercenter',user_id=user.id,tag=1))

 F.主要代碼:

#搜索功能
@bp.route('/search/')
def search():
qu = request.args.get('q')
ques = PostModel.query.filter(
and_(
PostModel.title.contains(qu)
)
).order_by('-create_time')
board_id = request.args.get('bd', type=int, default=None)
page = request.args.get(get_page_parameter(), type=int, default=1)
boards = BoardModel.query.all()
start = (page - 1) * config.PER_PAGE
end = start + config.PER_PAGE
total = 0

query_obj = PostModel.query.order_by(PostModel.create_time.desc())
if board_id:
query_obj = query_obj.filter_by(board_id=board_id)
posts = query_obj.slice(start, end)
total = query_obj.count()
else:
posts = query_obj.slice(start, end)
total = query_obj.count()
pagination = Pagination(bs_version=3, page=page, total=total, outer_window=0, inner_window=2)
context = {
'boards': boards,
'posts': ques,
'pagination': pagination,
'current_board': board_id

}

return render_template('front/front_index.html',**context)


#個人中心
@bp.route('/usercenter/<user_id>/<tag>')
@login_required
def usercenter(user_id,tag):
user = FrontUser.query.filter(FrontUser.id==user_id).first()
posts = PostModel.query.filter(PostModel.author_id == user_id).all()
context = {
'user':user,
'posts':posts
}
if tag == '1':
return render_template('front/front_usercenter.html',**context)
if tag == '2':
return render_template('front/front_user_apost.html',**context)

#點贊功能
@bp.route('/dianzan/',methods=['GET','POST'])
@login_required
def dianzan():
user_id=g.front_user.id
post_id=request.form.get('post_id')
dianzan=DianzanModel(user_id=user_id,post_id=post_id)
db.session.add(dianzan)
db.session.commit()
return redirect(url_for('front.post_detail',post_id=post_id))

#用戶上傳頭像
@bp.route('/avatar/<user_id>',methods=['POST'])
@login_required
def updata_acatar(user_id):
user = FrontUser.query.filter(FrontUser.id == user_id).first()
f = request.files['img']
basepath = os.path.dirname(__file__) # 當前文件所在路徑
upload_path = os.path.join('F:/godlike/static/img', f.filename) # 注意:沒有的文件夾一定要先創建,不然會提示沒有該路徑
f.save(upload_path)
user.avatar = 'img/' + f.filename
db.session.commit()
return redirect(url_for('front.usercenter',user_id=user.id,tag=1))


#用戶修改個人信息
@bp.route('/user_updata/<user_id>',methods=['GET','POST'])
@login_required
def user_updata(user_id):
if request.method == 'GET':
user= FrontUser.query.filter(FrontUser.id==user_id).first()
return render_template('front/front_user_updata.html',user=user)
else:
form = UserupdataForm(request.form)
if form.validate():
username = form.username.data
realname = form.realname.data
signature = request.form.get('signature')
user = g.front_user
user.username =username
user.realname = realname
user.signature = signature
db.session.commit()
return restful.success()
else:
return restful.params_error(form.get_error())


#用戶修改密碼
@bp.route('/resetpwd/',methods=['GET','POST'])
@login_required
def resetpwd():
if request.method == 'GET':
return render_template('front/front_resetpwd.html')
else:
form = ResetpwdForm(request.form)
if form.validate():
oldpwd = form.oldpwd.data
newpwd = form.newpwd.data
user = g.front_user
if user.check_password(oldpwd):
user.password = newpwd
db.session.commit()
# {"code":200,message=""}
# return jsonify({"code":200,"message":""})
return restful.success()
else:
return restful.params_error("舊密碼錯誤!")
else:
return restful.params_error(form.get_error())

#注銷
@bp.route('/logout/')
@login_required
def logout():
del session[config.FRONT_USER_ID]
return redirect(url_for('front.index'))
#注冊功能后台視圖
class SignupView(views.MethodView):
def get(self):
return_to = request.referrer
if return_to and return_to != request.url and safeutils.is_safe_url(return_to):
return render_template('front/front_signup.html',return_to=return_to)
else:
return render_template('front/front_signup.html')
def post(self):
form = SignupForm(request.form)
if form.validate():
email = form.email.data
username = form.username.data
password = form.password1.data
user = FrontUser(email=email,username=username,password=password)
db.session.add(user)
db.session.commit()
return restful.success()
else:
print(form.get_error())
return restful.params_error(message=form.get_error())
#登錄功能后台視圖
class SigninView(views.MethodView):
def get(self):
return_to = request.referrer
if return_to and return_to != request.url and return_to != url_for("front.signup") and safeutils.is_safe_url(
return_to):
return render_template('front/front_signin.html', return_to=return_to)
else:
return render_template('front/front_signin.html')
def post(self):
form =SigninForm(request.form)
if form.validate():
email = form.email.data
password = form.password.data
remember = form.remeber.data
user = FrontUser.query.filter_by(email=email).first()
if user and user.check_password(password):
session[config.FRONT_USER_ID]=user.id
if remember:
session.permanent= True
return restful.success()
else:
return restful.params_error(message='郵箱或密碼錯誤!')
else:
return restful.params_error(message=form.get_error())

首頁代碼:
{% from "common/_macros.html" import static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{% include "common/_heads.html" %}
<link rel="stylesheet" href="{{ static('front/css/front_base.css') }}">
<title>
{% block title %}{% endblock %}
</title>
{% block head %}{% endblock %}
</head>
<body>
<div class="banner">

<ul style="">
<li class="first"><a href="{{ url_for("front.index") }}">論壇首頁</a></li>
<li class="first"><a href="{{ url_for("front.index") }}">所有文章</a></li>
<li class="first"><a href="">熱門精選</a></li>
<li class="first"><a href="{{ url_for("front.apost") }}">發布帖子</a></li>
{# <!--<li class="first"><a href=""></a></li>-->#}
</ul>

<div class="banner_search">
<form action="{{ url_for('front.search') }}" method="get">
<input type="text" name="q" id="" value="" placeholder="請輸入關鍵字"/>
<button type="submit">搜索</button>
</form>
</div>
<div class="banner_right">
{% if g.front_user %}
<span id="login-tag" data-is-login="1" style="display: none;"></span>
<a href="{{ url_for('front.usercenter',user_id=g.front_user.id,tag="1") }}">{{ g.front_user.username }}</a>
<span>or</span>
<a href="{{ url_for('front.logout') }}">注銷</a>
{% else %}
<a href="{{ url_for('front.signin') }}">登錄</a>
<span>or</span>
<a href="{{ url_for("front.signup") }}">注冊</a>
{% endif %}
</div>
</div>


<div class="main-container">
{% block body %}{% endblock %}
</div>

</body>
</html>
帖子加精:
{% from "common/_macros.html" import static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>帖子加精</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
{% include "common/_heads.html" %}
<script src="{{ static("front/js/jiajing.js") }}"></script>
</head>
<body>
<div style="width: 1000px; margin: 50px auto; ">
<table class="table table-bordered" style="text-align: center">
<thead>
<tr>
<th>帖子標題</th>
<th>作者</th>
<th>發布時間</th>
<th>所屬板塊</th>
<th>操作</th>
</tr>
</thead>
{% for foo in post %}
<tr data-id="{{ foo.id }}" data-highlight="{{ 1 if foo.highlight else 0}}">

<th><a target="_blank" href="{{ url_for("front.post_detail",post_id=foo.id) }}">{{ foo.title }}</a></th>
<th>{{ foo.author.username }}</th>
<th>{{ foo.board.name }}</th>
<th>{{ foo.create_time }}</th>
<th>
{% if foo.highlight %}
<button type="button" class="btn btn-default highlight-btn">取消加精</button>
{% else%}
<button type="button" class="btn btn-danger highlight-btn">加精</button>
{% endif %}

</th>



</tr>
{% endfor %}
</table>
</div>
</body>
</html>

G.成品展示

論壇首頁:

注冊頁面:

 

格式不標准時:

 

登錄界面:

登錄成功:

 

發布帖子:

發布成功:

如果要設置帖子等級,需要數據庫后台改id:

 

點贊和評論功能:

 

 

個人中心:

 

 修改密碼:

 

 

密碼不一致時:

 

搜索帖子:

 

 

 個人總結:在本學期的課程設計當中,盡管是基於上學期的知識上的改進,但還是有點不完美的。在一開始要搭建各種虛擬環境,雖然有視頻教學,但大部分還是要靠自己去領悟理解。如何讓頁面布局更加美觀,完善具體功能,如何熟練運用Python+Flask+MysqL的web建設技術,都是要靠自己去摸索領悟的。不要害怕代碼報錯,一步步解決才能學到更多。




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM