中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

怎樣進(jìn)行公司網(wǎng)站建設(shè)企業(yè)網(wǎng)站模板源碼

怎樣進(jìn)行公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站模板源碼,wordpress 搜索分頁,青島網(wǎng)上房地產(chǎn)大家好,給大家分享一下python web開發(fā)案例教程,很多人還不知道這一點(diǎn)。下面詳細(xì)解釋一下?,F(xiàn)在讓我們來看看! 在線問答系統(tǒng) Flask Web開發(fā)項(xiàng)目介紹功能描述一、前端設(shè)計(jì)二、數(shù)據(jù)庫設(shè)計(jì)三、頁面功能開發(fā) 1.用戶模塊2.問答模塊四、總結(jié) Flask W…

大家好,給大家分享一下python web開發(fā)案例教程,很多人還不知道這一點(diǎn)。下面詳細(xì)解釋一下?,F(xiàn)在讓我們來看看!

在線問答系統(tǒng)
  • Flask Web開發(fā)
  • 項(xiàng)目介紹
  • 功能描述
  • 一、前端設(shè)計(jì)
  • 二、數(shù)據(jù)庫設(shè)計(jì)
  • 三、頁面功能開發(fā)
    • 1.用戶模塊
    • 2.問答模塊
  • 四、總結(jié)

Flask Web開發(fā)

請(qǐng)求到響應(yīng)
????用戶通過瀏覽器訪問url,會(huì)發(fā)送請(qǐng)求到服務(wù)器,服務(wù)器接收請(qǐng)求后會(huì)根據(jù)url規(guī)則找到對(duì)應(yīng)的視圖函數(shù)進(jìn)行處理,處理完后會(huì)把結(jié)果發(fā)送到瀏覽器端,瀏覽器接收到返回的內(nèi)容并呈現(xiàn)給用戶(得到響應(yīng))。

上下文對(duì)象
????在分派請(qǐng)求之前都會(huì)被激活,在請(qǐng)求處理完成后都被刪除python編寫一個(gè)皮卡丘。
請(qǐng)求上下文對(duì)象:
????Request:請(qǐng)求對(duì)象,封裝了客戶端發(fā)出的HTTP請(qǐng)求中的內(nèi)容。
????Session:用戶會(huì)話(dict)。各請(qǐng)求之間的數(shù)據(jù)共享。
應(yīng)用上下文對(duì)象:
????current_app:當(dāng)前激活程序的程序?qū)嵗?br /> ????g:處理請(qǐng)求時(shí)的臨時(shí)存儲(chǔ)對(duì)象,每次請(qǐng)求都會(huì)重設(shè)這個(gè)變量

Session與cookie:

  1. Session是在服務(wù)器端存儲(chǔ)數(shù)據(jù),而cookie是在客戶端存儲(chǔ)數(shù)據(jù)。
  2. Session依賴于cookie實(shí)現(xiàn),客戶端向服務(wù)器端發(fā)送請(qǐng)求時(shí)會(huì)帶上cookie,服務(wù)器端根據(jù)cookie的值找到Session中對(duì)應(yīng)的值(數(shù)據(jù)或用戶)。

請(qǐng)求報(bào)文:包括請(qǐng)求頭和請(qǐng)求體
常用參數(shù):
????method:GET/POST
????form:POST請(qǐng)求數(shù)據(jù)dict
????args:GET請(qǐng)求數(shù)據(jù)dict
????values:POST請(qǐng)求數(shù)據(jù)和GET請(qǐng)求數(shù)據(jù)集合dict
????files:上傳的文件數(shù)據(jù)dict
????cookies:請(qǐng)求中cookie dict
????headers:HTTP請(qǐng)求頭

響應(yīng)報(bào)文:包括響應(yīng)頭和響應(yīng)體
????響應(yīng):字符串,元組(response,status,headers)
????響應(yīng)元組:response-響應(yīng)內(nèi)容;status-響應(yīng)狀態(tài)碼;headers-響應(yīng)頭信息(dict)。

項(xiàng)目介紹

????該系統(tǒng)是基于Python的Web開發(fā)實(shí)戰(zhàn)項(xiàng)目,前端框架采用Bootstrap,后端采用Flask框架,模板引擎為Jinja2,數(shù)據(jù)庫采用Mysql8.0,開發(fā)環(huán)境為Python3.9,Flask2.0.1。

功能描述

????該項(xiàng)目通過藍(lán)圖改造實(shí)現(xiàn)了項(xiàng)目模塊化,主要分為用戶模塊和問答模塊,用戶模塊包括登錄、注冊(cè)、個(gè)人主頁。問答模塊包括首頁,關(guān)注頁,詳情頁,寫文章頁。
????用戶可以登錄,注冊(cè),并在個(gè)人主頁查看和修改個(gè)人信息等。
????用戶可以發(fā)問題,關(guān)注問題,回答問題,也可以收藏回答,點(diǎn)贊回答,點(diǎn)贊評(píng)論,評(píng)論回答等。

一、前端設(shè)計(jì)

????前端主要采用了HTML標(biāo)簽,CSS樣式,JS語言。布局主要采用的是Flex布局和Bootstrap柵格布局,也用到了Bootstrap許多內(nèi)置的全局CSS樣式和組件以及JS插件,同時(shí)用到了iconfont阿里圖標(biāo)庫,再加上自己對(duì)頁面樣式的改寫和優(yōu)化,這樣下來,基本搭建了項(xiàng)目的前端頁面。

二、數(shù)據(jù)庫設(shè)計(jì)

????使用flask_sqlalchemy擴(kuò)展建立ORM模型,難點(diǎn)主要在對(duì)表之間關(guān)系的理解以及建立表與表的關(guān)系屬性,常見的關(guān)系主要是一對(duì)一和一對(duì)多。
例如在UserProfile模型下建立與User模型一對(duì)一屬性:
user = db.relationship('User', backref=db.backref('profile', uselist=False))
在Question模型下建立與User模型一對(duì)多屬性:
user = db.relationship('User', backref=db.backref('question_list', lazy='dynamic'))
????這里采用lazy=‘dynamic’(懶加載):不是直接加載這些數(shù)據(jù),SQLAlchemy會(huì)返回一個(gè)查詢對(duì)象,在加載數(shù)據(jù)前可以過濾(提取)它們,不可用在一對(duì)一和多對(duì)一關(guān)系中

三、頁面功能開發(fā)

1.用戶模塊

????該模塊難點(diǎn)主要在登錄,這里采用了第三方擴(kuò)展flask_login。

登錄流程:

  1. 用戶在登陸表單輸入用戶名和密碼。
  2. 表單驗(yàn)證包括驗(yàn)證用戶名和密碼是否正確,用戶名規(guī)定為手機(jī)號(hào),用戶名和密碼不為空,用戶狀態(tài)為激活狀態(tài)等。
  3. 通過表單驗(yàn)證,執(zhí)行登錄操作。
  4. 記錄用戶登錄信息。
  5. 跳轉(zhuǎn)到上一次訪問的頁面或首頁。

開發(fā)流程:

  1. 編寫登錄表單并渲染到模板中。
  2. 編寫表單驗(yàn)證,包括自定義表單驗(yàn)證,驗(yàn)證用戶名和密碼是否正確。注:由于數(shù)據(jù)庫中的密碼是加密存儲(chǔ),驗(yàn)證時(shí)需要拿到表單中的用戶名和密碼,并將密碼加密后再驗(yàn)證
  3. 通過login_user()執(zhí)行登錄操作,可以記錄、保存當(dāng)前成功登錄的用戶(current_user)。
  4. 使用ORM模型保存用戶登錄的相關(guān)信息到數(shù)據(jù)庫中。
  5. 登陸成功后重定向,這里添加了一個(gè)隱藏表單域用來保存用戶上一次試圖訪問的頁面url,并在視圖函數(shù)中得到相應(yīng)的值。
    <input type="hidden" name="next" value="{{ next_url|d('') }}">
    next_url = request.values.get('next', url_for('qa.index'))

部分效果展示:
在這里插入圖片描述
在這里插入圖片描述

2.問答模塊

????該模塊難點(diǎn)主要在關(guān)注頁面中問答列表的分頁異步加載,詳情頁面中評(píng)論功能的開發(fā)和評(píng)論的分頁異步加載等。接口使用restful風(fēng)格接口,并通過Jquery中的ajax調(diào)用接口。

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

實(shí)現(xiàn)流程:

  1. 后端(視圖層)編寫API
  2. 前端(模板層)調(diào)用API
  3. 渲染頁面,綁定功能。

部分代碼:

@qa.route('/qa/list')
def question_list():"""異步查詢問題數(shù)據(jù)列表"""try:per_page = 2page = request.args.get('page', 1, type=int)lst = []  # 用來保存當(dāng)前用戶關(guān)注的問題id# 只查詢當(dāng)前用戶關(guān)注的問題question_follow = QuestionFollow.query.filter_by(user_id=current_user.id).all()for item in question_follow:lst.append(item.q_id)page_data = Question.query.filter(Question.id.in_(lst)).paginate(page=page, per_page=per_page)data = render_template('qa_list.html', page_data=page_data)return {'code': 0, 'data': data}except Exception as e:print(e)data = ''return {'code': 1, 'data': data}
<>$(function () {// 要填充的容器var container = $('#id-qa-ls');// 默認(rèn)頁碼為1var page = 1;// 給按鈕綁定點(diǎn)擊事件$('#id-load-more').click(function () {// 前端模板層調(diào)用數(shù)據(jù)接口$.get('{{ url_for("qa.question_list") }}',{'page': page},function (result) {console.log(result);if (result.code === 0) {var res = result.dataconsole.log(res);// 手動(dòng)綁定DOM事件// 1.構(gòu)建JQ對(duì)象var html = $(res);// 2.為對(duì)象里面的一些元素綁定事件,指定事件范圍$('.more', html).click(function () {$(this).parent().addClass('hidden');$(this).parent().next().removeClass('hidden')})$('.more', html).click(function () {$(this).parent().addClass('hidden');$(this).parent().prev().removeClass('hidden')})// 添加到容器container.append(html);// 加載完成后,頁碼+1page += 1;} else {window.alert('接口請(qǐng)求失敗');}})})})</>
@qa.route('/comments/<int:answer_id>', methods=['GET', 'POST'])
def comments(answer_id):"""坪論"""answer = Answer.query.get(answer_id)question = answer.questionif request.method == 'POST':# 添加一條評(píng)論try:# 判斷用戶是否登錄if not current_user.is_authenticated:result = {'code': 1, 'message': '請(qǐng)登錄'}return jsonify(result), 400# 1.獲取前端傳遞的參數(shù)content = request.form.get('content', '')reply_id = request.form.get('reply_id', None)# 2.保存到數(shù)據(jù)庫comment_obj = Comment(content=content, user=current_user,answer=answer, question=question, reply_id=reply_id)db.session.add(comment_obj)db.session.commit()# 如果添加成功,則返回result和201狀態(tài)碼result = {'code': 0, 'message': '評(píng)論成功'}return jsonify(result), 201except Exception as e:print(e)result = {'code': 1, 'message': '服務(wù)器正忙,請(qǐng)稍后重試'}# jsonify將字典轉(zhuǎn)成json字符串return jsonify(result), 400else:# GET獲取坪論列表try:page = int(request.args.get('page', 1))page_data = answer.comment_list().paginate(page=page, per_page=3)data = render_template('comments.html', page_data=page_data, answer=answer)  # 獲取html內(nèi)容return jsonify({'code': 0, 'data': data, 'meta': {'page': page}}), 200except Exception as e:print(e)return jsonify({'code': 1, 'data': '', 'message': '服務(wù)器正忙'}), 500
		// 發(fā)表評(píng)論function bindCommentPublishEvent(html) {// 查詢發(fā)表評(píng)論表單var form = $('.comment-publish', html);// 給發(fā)表評(píng)論表單下的.btn綁定事件$('.btn', form).click(function () {var _form = $(this).parent();var content = $('input[name=content]', _form);// 將表單內(nèi)容序列化成一個(gè)字符串var data = _form.serialize();$.ajax({url: {% if answer %}'{{ url_for("qa.comments", answer_id=answer.id) }}'{% else %}''{% endif %},method: 'POST',data: data,complete: function (res) {console.log(res);if (res.status === 201) {window.alert(res.responseJSON.message);// 清空評(píng)論框content.val('');// 重新加載頁面location.reload();} else if (res.status === 400) {window.alert(res.responseJSON.message);window.location.href = '{{ url_for("accounts.login") }}';} else {window.alert('請(qǐng)求失敗,請(qǐng)稍后重試');}}})})}
        // 評(píng)論列表的異步加載var comment_ls = $('#id-comment-ls');var page = 1;function loadPageData(page) {page = page || 1$.ajax({url: {% if answer %}'{{ url_for("qa.comments", answer_id=answer.id) }}'{% else %}''{% endif %},method: 'GET',data: {page: page},complete: function (res) {// console.log('res:', res);if (res.status === 200) {var result = res.responseJSON;if(result) {if (result.code === 0) {var html = $(result.data);// 評(píng)論回復(fù)按鈕事件綁定bindReplyEvent(html);// 發(fā)布按鈕事件綁定bindCommentPublishEvent(html);// 點(diǎn)贊按鈕事件綁定bindCommentEvent(html);comment_ls.empty().append(html);}}} else {window.alert('服務(wù)器正忙')}}})}$('.pager .previous').click(function () {page = page - 1;loadPageData(page);})$('.pager .next').click(function () {page = page + 1;loadPageData(page);});// 默認(rèn)加載第一頁數(shù)據(jù)loadPageData(page);

部分效果展示:
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

注:通過ajax請(qǐng)求時(shí),需要重新手動(dòng)綁定DOM事件

異步調(diào)用接口的好處:提升查詢效率,提升用戶體驗(yàn),降低代碼耦合度,維護(hù)性更強(qiáng)。

四、總結(jié)

????本次項(xiàng)目讓我更加深刻地體會(huì)到了前端框架的強(qiáng)大與便利,加深了我對(duì)Flask框架的認(rèn)識(shí),也更加了解了從客戶端到服務(wù)器端,從請(qǐng)求到響應(yīng)的過程,最重要的是讓我認(rèn)識(shí)到了Restful接口風(fēng)格以及學(xué)會(huì)了怎樣編寫接口,并通過ajax異步請(qǐng)求調(diào)用接口。此次項(xiàng)目基本完成了在線問答系統(tǒng)的相關(guān)功能。

更多內(nèi)容可前往http://39.105.148.140:8001/ 進(jìn)行查看。

http://www.risenshineclean.com/news/65796.html

相關(guān)文章:

  • 施工企業(yè)資質(zhì)包括哪些優(yōu)化大師手機(jī)版下載安裝app
  • 知名網(wǎng)站制作全包怎么建自己的網(wǎng)站?
  • 文化建設(shè)的具體措施seo是什么崗位簡(jiǎn)稱
  • 重慶哪家在做網(wǎng)站建設(shè)競(jìng)價(jià)廣告
  • 網(wǎng)站在哪里搜索北京seo包年
  • 鎮(zhèn)江網(wǎng)站建設(shè)找思創(chuàng)網(wǎng)絡(luò)今日頭條熱榜
  • 南京越城建設(shè)集團(tuán)有限公司網(wǎng)站小紅書kol推廣
  • 佛山網(wǎng)站排名推廣有沒有永久免費(fèi)crm
  • 個(gè)人網(wǎng)站備案容易嗎最近最新新聞
  • 萬網(wǎng)網(wǎng)站空間服務(wù)范圍及費(fèi)用seo的形式有哪些
  • 拉薩網(wǎng)站制作公司新余seo
  • 長(zhǎng)沙市網(wǎng)站推廣公司推廣計(jì)劃書范文
  • 網(wǎng)站抓取壓力高重慶排名優(yōu)化整站優(yōu)化
  • 全國(guó)哪個(gè)餐飲品牌的網(wǎng)站做的好處百度關(guān)鍵詞屏蔽
  • 國(guó)內(nèi)互聯(lián)網(wǎng)大廠有哪些合肥seo建站
  • 短視頻素材網(wǎng)站免費(fèi)大推薦短視頻seo營(yíng)銷系統(tǒng)
  • 學(xué)校網(wǎng)站建設(shè)方案模板下載表白網(wǎng)站制作
  • 網(wǎng)站建設(shè)需要編程嗎個(gè)人怎么注冊(cè)自己的網(wǎng)站
  • asp網(wǎng)站跳轉(zhuǎn)瀏覽器如何給公司做網(wǎng)絡(luò)推廣
  • 做pc端的網(wǎng)站首頁尺寸是多少網(wǎng)絡(luò)營(yíng)銷渠道類型有哪些
  • 青島做視頻的網(wǎng)站設(shè)計(jì)引擎優(yōu)化seo是什么
  • 響應(yīng)式網(wǎng)站用什么技術(shù)做百度搜索廣告
  • 11108給換成119333做網(wǎng)站太原高級(jí)seo主管
  • 昆明免費(fèi)網(wǎng)站制作網(wǎng)絡(luò)運(yùn)營(yíng)工作內(nèi)容
  • 蘇州網(wǎng)站建設(shè)價(jià)格seo排名優(yōu)化關(guān)鍵詞
  • 怎么查看網(wǎng)站誰做的北京網(wǎng)絡(luò)推廣有哪些公司
  • wordpress博客美化百度關(guān)鍵詞優(yōu)化系統(tǒng)
  • 做爰全國(guó)網(wǎng)站金融網(wǎng)站推廣圳seo公司
  • 網(wǎng)站開發(fā)用什么軟件甘肅seo網(wǎng)站
  • 如何查詢網(wǎng)站注冊(cè)信息查詢免費(fèi)創(chuàng)建網(wǎng)站