Python+Flask+MysqL的web建設技術開發一個網站
一、摘要
flask是一個很精簡,靈活的框架,對於web的開發非常的好,具有jinja2強大的模板引擎的支持。flask框架的一個擴展就是sqlalchemy,
sqlalcheny是flask的一個擴展。sqlalcheny是一個強大的關系型數據庫框架,它是一個框架,並不是數據庫。sqlalcheny數據庫的操作得益於我們的ORM技術,將繁瑣的數據庫操作轉化為我們的python的類,其實還是轉化為sql語句來操作數據庫,這就是他的強大的地方,同時特提供了數據庫原生的SQL底存功能。sqlalcheny提供了高層 ORM,也提供了使用數據庫原生 SQL 的低層功能。
二、系統概要說明
1、設計數據庫,數據庫設計是網站設計的重點,需要對網站需求進行分析,設計適合網站需求的數據庫。
2、註冊頁面,設計網站需要用戶的使用,註冊則是重要的一部分,用戶註冊需要對用戶信息的管理,因此,需要數據庫的連接,進行用戶註冊的驗證。
3、登錄功能,在用戶註冊了賬號後,擁有了該網站的使用權,則可以進行登錄,而登錄也需要數據庫的驗證。
4、用戶發布問答,該網站是新聞信息發布平臺,用戶可以將身邊的見聞發布到網站,此功能也需要數據庫的連接,將用戶發表的問答存到數據庫的question表中,以用戶唯一的id號作為外鍵。
5、用戶發布新聞問答後則會跳到網站首頁,首頁是展示該網站的所以新聞信息,以發布的最新日期排序進行展示,用戶可根據興趣點擊查看網站的新聞標題,進入新聞的詳情頁面,了解新聞的具體信息。
6、新聞詳情頁中具有評論及推薦文章功能,用戶可對新聞進行評論發表還可對文章進行點贊及收藏,此操作過程存入數據庫的comment表中,以用戶id、新聞id作為外鍵;網站還根據用戶感興趣的新聞推薦相應類型的新聞文章。
7、個人中心頁面,網站根據用戶的活躍度,呈現用戶發布的新聞,評論文章,收藏文章以及點贊。
8、用戶個人信息更改頁面,數據庫中存儲了用戶註冊時的信息,當用戶要更改個人信息時,可進入用戶更改信息頁面對個人信息進行修改,信息修改完成保存後則會重新寫入用戶user表中,更新用戶個人信息。
9、網站具有模糊搜索功能,當用戶查找相應信息是,可根據用戶輸入的信息進行模糊搜索,提高用戶的體驗度。
10、密碼保護功能,用戶註冊時設置的密碼存儲到數據庫中,此時數據會將用戶的密碼進行加密,提高用戶使用的安全性。
三、網站結構設計
1、父模板模塊
2、首頁、發布列表顯示
3、註冊頁面
4、登錄頁面
5、發布新聞頁面
6、新聞詳細頁,點贊,收藏,評論,推薦文章
7、更改個人信息頁面
8、個人 信息頁面
四、模塊詳細設計
1、首頁模塊
@app.route(‘/‘) def index(): if request.args.get(‘info‘): info = request.args.get(‘info‘) else: info = None; context = { ‘questions‘: Question.query.order_by(‘-creat_time‘).all(), ‘cf‘: Cf.query.all(), ‘info‘: info, ‘hot‘: Question.query.order_by(‘-click‘).all()[0:5] } return render_template(‘index.html‘, **context)
2、註冊模塊
@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‘) user = User.query.filter(User.username == username).first() if user: return ‘error:user exitst‘ else: user = User(username=username, password=password) db.session.add(user) # 加入數據庫 db.session.commit() return redirect(url_for(‘login‘))
3、登錄模塊
@app.route(‘/login/‘, methods=[‘GET‘, ‘POST‘]) def login(): if request.method == ‘GET‘: return render_template(‘login.html‘) else: username = request.form.get(‘username‘) password = request.form.get(‘password‘) user = User.query.filter(User.username == username).first() if user: if user.check_password(password): session[‘username‘] = user.username session[‘user_id‘] = user.id session.permanent = True # 重新定位到首頁 return redirect(url_for(‘index‘)) else: # 重新定位到註冊 return redirect(url_for(‘login‘)) else: return redirect(url_for(‘login‘))
4、發布模塊
@app.route(‘/question‘, methods=[‘GET‘, ‘POST‘]) @loginFirst def question(): if request.method == ‘GET‘: cf = Cf.query.all() return render_template(‘question.html‘, cf=cf) else: title = request.form.get(‘title‘) detail = request.form.get(‘detail‘) author_id = request.form.get(‘author_id‘) cf = request.form.get(‘cf‘) question = Question(title=title, detail=detail, author_id=author_id, cf=cf) db.session.add(question) # 加入數據庫 db.session.commit() return redirect(url_for(‘index‘))
5、評論模塊
@app.route(‘/answer/‘, methods=[‘GET‘, ‘POST‘]) def answer(): if request.method == ‘POST‘: question_id = request.form.get(‘question_id‘) author_id = request.form.get(‘author_id‘) detail = request.form.get(‘detail‘) comment = Comment(question_id=question_id, author_id=author_id, detail=detail) db.session.add(comment) db.session.commit() return redirect(url_for(‘detail‘, question_id=question_id))
@app.route(‘/commentaries/<user_id>‘)
def commentaries(user_id):
userCommentaries = Comment.query.filter(Comment.answer_id == user_id).all()
num = len(userCommentaries)
id = session.get(‘user_id‘)
if id:
user = User.query.filter(User.id == id).first()
else:
user = {}
return render_template(‘commentaries.html‘, userCommentaries=userCommentaries, user=user, num=num)
6、更改個人信息模塊
@app.route(‘/uploadLogo/<user_id>‘, methods=[‘GET‘, ‘POST‘]) def uploadLogo(user_id): user = User.query.filter(User.id == user_id).first() f = request.files[‘logo‘] basepath = os.path.dirname(__file__) # 當前文件所在路徑 upload_path = os.path.join(basepath, ‘static/uploads‘, f.filename) # 註意:沒有的文件夾一定要先創建,不然會提示沒有該路徑 f.save(upload_path) user.icon = ‘uploads/‘ + f.filename db.session.commit() return redirect(url_for(‘setPassword‘, id=user_id)); @app.route(‘/setPassword/<id>‘, methods=[‘GET‘, ‘POST‘]) @loginFirst def setPassword(id): if request.method == ‘GET‘: return render_template(‘setPassword.html‘) else: user = User.query.filter(User.id == id).first() if user: if user.check_password(request.form.get(‘old‘)): user.password = request.form.get(‘new1‘) db.session.commit() info = ‘修改成功‘ else: info = ‘原密碼錯誤‘ else: info = ‘未知錯誤‘ return redirect(url_for(‘index‘, info=info))
7、個人信息模塊
@app.route(‘/comment/<user_id>/<num>‘) def comment(user_id, num): user = User.query.filter(User.id == user_id).first() content = { ‘comment‘: user.comment, ‘questions‘: user.question, ‘user2‘: user, } if (num == ‘1‘): return render_template(‘subComment1.html‘, **content, title=‘全部問題‘) elif (num == ‘2‘): return render_template(‘subComment2.html‘, **content) elif (num == ‘3‘): return render_template(‘subComment3.html‘, **content) elif (num == ‘4‘): content = { ‘comment‘: user.comment, ‘questions‘: user.collection.all(), ‘user2‘: user, } return render_template(‘subComment1.html‘, **content, title=‘我的收藏‘) else: return render_template(‘subComment1.html‘, **content) @app.route(‘/c/<cf>‘) def c(cf): content = { ‘questions‘: Question.query.filter(Question.cf == cf).order_by(‘-creat_time‘).all(), ‘cf‘: Cf.query.all(), ‘hot‘: Question.query.order_by(‘-click‘).all()[0:5] } return render_template(‘index.html‘, **content)
8、模糊搜索模塊
@app.route(‘/search‘) def search(): qu = request.args.get(‘q‘) c = ‘‘ if request.args.get(‘c‘) == ‘‘ else request.args.get(‘c‘) y = ‘‘ if request.args.get(‘y‘) == ‘‘ else request.args.get(‘y‘) query = Question.query.filter( or_( Question.title.contains(qu), Question.detail.contains(qu), ), Question.cf.like(‘%‘ + c + ‘%‘), Question.creat_time.like(‘%‘ + y + ‘%‘), ).order_by(‘-creat_time‘).all() context = { ‘questions‘: query, ‘cf‘: Cf.query.all(), ‘hot‘: Question.query.order_by(‘-click‘).all()[0:5] } return render_template(‘index.html‘, **context)
9、詳情頁面
@app.route(‘/detail/<question_id>‘, methods=[‘GET‘, ‘POST‘]) @loginFirst def detail(question_id): quest = Question.query.filter(Question.id == question_id).first() u = User.query.filter(User.id == session.get(‘user_id‘)).first() if request.method == ‘POST‘: if request.form.get(‘click‘) == ‘1‘: quest.click = quest.click + 1 if request.form.get(‘collection‘) == ‘1‘: user = u user.collection.append(quest) db.session.add(user) col = u.collection.filter_by(id=question_id).first() if col is None: col = {} comment = Comment.query.filter(Comment.question_id == question_id).order_by(‘-creat_time‘).all() quest.look = quest.look + 1 content = { ‘ques‘: quest, ‘comment‘: comment, ‘col‘: col, ‘questions‘: Question.query.filter(Question.cf == quest.cf).all(), } return render_template(‘detail.html‘, **content)
五、數據庫設計
Collection = db.Table( ‘collection‘, db.Column(‘id‘, db.Integer, primary_key=True, autoincrement=True), db.Column(‘book_id‘, db.Integer, db.ForeignKey(‘question.id‘)), # 評論對應的文章的id db.Column(‘collection‘, db.Integer, db.ForeignKey(‘user.id‘)), # 收藏用戶的id db.Column(‘createdate‘, db.DATETIME) # 發布時間 ) class User(db.Model): __tablename__ = ‘user‘ # 建立一個表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) say = db.Column(db.String(50)) icon = db.Column(db.String(50)) collection = db.relationship(‘Question‘, secondary=Collection, backref=db.backref(‘user‘, lazy=‘dynamic‘), lazy=‘dynamic‘) @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): return check_password_hash(self._password, row_password) 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‘)) creat_time = db.Column(db.DateTime, default=datetime.now()) detail = db.Column(db.TEXT, nullable=False) question = db.relationship(‘Question‘, backref=db.backref(‘comment‘)) author = db.relationship(‘User‘, backref=db.backref(‘comment‘, order_by=creat_time.desc)) 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) creat_time = db.Column(db.DateTime, default=datetime.now) author_id = db.Column(db.Integer, db.ForeignKey(‘user.id‘)) cf = db.Column(db.Integer, db.ForeignKey(‘cf.id‘)) look = db.Column(db.Integer) click = db.Column(db.Integer) author = db.relationship(‘User‘, backref=db.backref(‘question‘)) cfClass = db.relationship(‘Cf‘, backref=db.backref(‘question‘)) # 分類 class Cf(db.Model): __tablname__ = ‘cf‘ id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 數據庫唯識別id name = db.Column(db.String(30)) # 文章名稱 context = db.Column(db.TEXT) # 分類內容
1、分類表
2、收藏表
3、評論表
4、發布新聞表
5、用戶表
Python+Flask+MysqL的web建設技術開發一個網站