博客目錄:
......
十、基于Django+mysql的點(diǎn)餐系統(tǒng)設(shè)計(jì)-第十篇(H5手機(jī)移動(dòng)端點(diǎn)餐:登錄)
十一、基于Django+mysql的點(diǎn)餐系統(tǒng)設(shè)計(jì)-第十一篇(H5手機(jī)移動(dòng)端點(diǎn)餐:購(gòu)物車操作)
十二、基于Django+mysql點(diǎn)餐系統(tǒng)設(shè)計(jì)-第十二篇(移動(dòng)端:會(huì)員下單處理)
本章源碼下載地址:
https://github.com/hopeSuceess/testorder/tree/testorder_20220629_01購(gòu)物車下完單后要進(jìn)行展示,本次來編寫訂單的展示。首先訂單展示在前端頁(yè)面哪呢?根據(jù)設(shè)計(jì)會(huì)將訂單展示放在"我的-我的訂單"下?,F(xiàn)在點(diǎn)擊"我的",還沒有反應(yīng),需要先實(shí)現(xiàn)"我的"模塊功能。
在mobile/urls.py中創(chuàng)建個(gè)人中心路由
#會(huì)員中心 path(member,member.index, name="mobile_member_index"), #會(huì)員中心首頁(yè)在mobile/views下創(chuàng)建member.py并創(chuàng)建index函數(shù)
def index(request): 個(gè)人中心首頁(yè) return render(request, "mobile/member.html")在templates/mobile下創(chuàng)建member.html,頁(yè)面上的返回鍵有兩種方式,一種是加個(gè)"個(gè)人中心"標(biāo)頭,返回鍵調(diào)用API接口;另一種方式是通過href標(biāo)簽的方式返回制定的頁(yè)面
第一種展現(xiàn)方式:點(diǎn)擊返回后,返回到上一頁(yè)即首頁(yè):
...... {% block mainbody %} <!--頭部--> <header> <div class="header"> <h1>個(gè)人中心</h1> <a href="javascript:window.history.back();" class="return"><i></i></a> </div> </header> <!--內(nèi)容區(qū)--> <article class="main-container"> <div class="member-header"> <p> </p> <div class="memberhead"><img src="{% static mobile/img/head03.jpg %}" alt=""><i class="icon-woman"></i></div> <ul> ......第二種展現(xiàn)方式:點(diǎn)擊返回后,返回到上一頁(yè)即首頁(yè):
{% block mainbody %} <!--內(nèi)容區(qū)--> <article class="main-container"> <div class="member-header"> <button class="button" onclick="location.href={% url mobile_index %}"><span class="return"><i></i></span></button> <p> </p> <div class="memberhead"><img src="{% static mobile/img/head03.jpg %}" alt=""><i class="icon-woman"></i></div> <ul> ......兩種表現(xiàn)形式,大家可根據(jù)喜好選擇。member.html完整代碼如下
{% extends mobile/base.html %} {% load static %} {% block mainbody %} <!--頭部--> <header> <div class="header"> <h1>個(gè)人中心</h1> <a href="javascript:window.history.back();" class="return"><i></i></a> </div> </header> <!--內(nèi)容區(qū)--> <article class="main-container"> <div class="member-header"> {# <button class="button" onclick="location.href={% url mobile_index %}"><span class="return"><i></i></span></button>#} <p> </p> <div class="memberhead"><img src="{% static mobile/img/head03.jpg %}" alt=""><i class="icon-woman"></i></div> <ul> <li class="line-w"><b> </b><h1></h1></li> </ul> <div class="waves1 icon-waves"></div> <div class="waves2 icon-waves"></div> <div class="waves3 icon-waves"></div> </div> <div class="list"> <ul class="line"> <li onclick="location.href={% url mobile_member_orders %}"><i class="icon-allorders"></i>我的訂單<span class="icon-arrowright"></span></li> </ul> <ul class="line"> <li onclick="location.href=member-data.html"><i class="icon-head"></i>我的資料<span class="icon-arrowright"></span></li> <li onclick="location.href=member-pwd.html"><i class="icon-pwd"></i>修改密碼<span class="icon-arrowright"></span></li> <li onclick="location.href=member-coupon.html"><i class="icon-coupons"></i>優(yōu)惠券<span class="icon-arrowright"></span></li> <li onclick="location.href=member-Addrees.html"><i class="icon-address"></i>收貨地址<span class="icon-arrowright"></span></li> </ul> <ul class="line"> <li onclick="location.href={% url mobile_member_logout %}"><i class="icon-out"></i>退出</li> </ul> </div> </article> {% endblock %}到這"我的"模塊已經(jīng)編寫完成,啟動(dòng)工程,訪問
http://127.0.0.1:8000/mobile/ ,點(diǎn)擊"我的",跳轉(zhuǎn)到個(gè)人中心頁(yè)面接下來開始實(shí)現(xiàn)個(gè)人中心-我的訂單功能。到現(xiàn)在為止,咱們實(shí)現(xiàn)了很多功能了,所有的功能都是在Django框架下,遵從MTV思想和路由控制器實(shí)現(xiàn)的?,F(xiàn)在要說的"我的訂單"功能也不例外,在這里就不事無巨細(xì)的敘述了。重點(diǎn)說下view層后端代碼的實(shí)現(xiàn)邏輯和template層前端代碼的實(shí)現(xiàn)邏輯。
先來說下view層后端的代碼邏輯,想要實(shí)現(xiàn)的功能是什么呢?可以通過該會(huì)員獲取其下的訂單信息,前端如果點(diǎn)擊不同狀態(tài)的訂單狀態(tài)可以獲取對(duì)應(yīng)訂單狀態(tài)下的訂單,每個(gè)展示的訂單只展示前4條訂單詳情。針對(duì)以上需求,開發(fā)人員該怎么辦呢?看以下代碼編寫
def orders(request): 個(gè)人中心瀏覽訂單 mid = request.session[mobileuser][id] #獲取當(dāng)前會(huì)員id號(hào) olist = Orders.objects.filter(member_id=mid) # 獲取、判斷并封裝狀態(tài)status搜索條件 status = request.GET.get(status, ) if status != : olist = olist.filter(status=status) # 按id號(hào)做降序排序 list2 = olist.order_by("-id") order_status = ["無","排隊(duì)中","已撤銷","已完成"] # 遍歷訂單,關(guān)聯(lián)其他表數(shù)據(jù)(訂單詳情,店鋪信息) for vo in list2: plist = OrderDetail.objects.filter(order_id=vo.id)[:4] # 獲取前4條 vo.plist = plist vo.statusinfo = order_status[vo.status] # 轉(zhuǎn)換訂單狀態(tài) return render(request, "mobile/member_orders.html",{"orderslist":list2})咱們來分析下上面的代碼:通過request.session[mobileuser][id]在緩存中獲取到該會(huì)員id號(hào),再用Orders.objects.filter(member_id=mid)匹配到該會(huì)員的所有訂單。至于status = request.GET.get(status, ) if status != : olist = olist.filter(status=status)這三段代碼,和前端頁(yè)面緊密相連,當(dāng)前端點(diǎn)擊某狀態(tài)時(shí),后端 經(jīng)過處理篩選出該狀態(tài)下的訂單。olist.order_by("-id")的功能是根據(jù)id號(hào)對(duì)訂單進(jìn)行降序出路。
每一種語(yǔ)言的基礎(chǔ)學(xué)好都非常重要,像這次,列表運(yùn)用的非常精妙。order_status = ["無","排隊(duì)中","已撤銷","已完成"]定義了一個(gè)名叫order_status的列表,列表中有“無”、“排隊(duì)中”、"已撤銷"、“已完成”四個(gè)元素,vo.statusinfo = order_status[vo.status]中vo.status是在數(shù)據(jù)庫(kù)中獲取訂單的狀態(tài),數(shù)據(jù)庫(kù)中的訂單狀態(tài)是以數(shù)字的形式存放的,現(xiàn)在將vo.status作為索引放到order_status中,打個(gè)比方,當(dāng)前端的用戶點(diǎn)擊"排隊(duì)中"時(shí),“排隊(duì)中"對(duì)應(yīng)的status=1,后端先利用olist = olist.filter(status=status)將排隊(duì)中的訂單篩選出來,現(xiàn)在訂單狀態(tài)都是"排隊(duì)中",這次再通過vo.statusinfo = order_status[vo.status] 將排隊(duì)中的訂單以文字形式展示出來。既然vo.statusinfo = order_status[vo.status] 是將數(shù)據(jù)渲染到前端,那么前端對(duì)這些數(shù)據(jù)有用,等說到前端了繼續(xù)講解。
因?yàn)槊總€(gè)訂單訂餐數(shù)量大于等于1,若將每個(gè)訂單的訂餐數(shù)量展示出來,如果某個(gè)訂單訂餐數(shù)量多,可能頁(yè)面空間不足。怎么辦呢?展示每個(gè)訂單的前4條餐品詳情信息。將功能邏輯以代碼形式展現(xiàn)
for vo in list2: plist = OrderDetail.objects.filter(order_id=vo.id)[:4] # 獲取前4條 vo.plist = plist后端說完了,咱們?cè)偈崂硐虑岸?。在后端代碼梳理中咱們說了會(huì)根據(jù)前端對(duì)訂單狀態(tài)的點(diǎn)擊而有對(duì)應(yīng)訂單邏輯處理。那么前端怎么點(diǎn)擊訂單狀態(tài),訂單狀態(tài)又是以什么前端代碼形式展現(xiàn)的呢?看下面代碼
<!--選項(xiàng)卡-->
<nav class="memberOrder-nav line">
<a href="{% url mobile_member_orders %}" class="line select">全部</a>
<a href="{% url mobile_member_orders %}?status=1" class="line">排隊(duì)中</a>
<a href="{% url mobile_member_orders %}?status=3">已完成</a>
</nav>
<div class="memberOrder-header"></div>
默認(rèn)的是全部,status關(guān)鍵字不會(huì)傳到后端,如果點(diǎn)擊排隊(duì)中或已完成,status=1或status=3會(huì)將信息傳到后端,后端進(jìn)行邏輯判斷。前端的展示頁(yè)面如下
訂單狀態(tài)說完了,接著說下前端怎么接受后端渲染過來的數(shù)據(jù) {% for order in orderslist %}
<div class="memberOrder-list line" onclick="location.href={% url mobile_member_detail order.id %} ">
<p><b>訂單編號(hào):</b>{{ order.id }}<span>({{ order.statusinfo }})</span></p>
<div class="order-product line">
<ul>
<li>
{% for vo in order.plist %}
<img src="{% static uploads/product/ %}{{ vo.product.cover_pic }}" alt="">
{% endfor %}
</li>
</ul>
</div>
<p>
<b>總價(jià):</b><span>¥{{ order.money }}</span>元
<b>下單時(shí)間:</b>{{ order.create_at|date:Y-m-d H:i }}
</p>
</div>
{% endfor %}
看上面的代碼,首先遍歷后端傳過來的數(shù)據(jù)orderslist,onclick="location.href={% url mobile_member_detail order.id %} 的意思點(diǎn)擊某個(gè)訂單會(huì)跳到該訂單的詳情頁(yè),這個(gè)后面會(huì)詳細(xì)講。這里可以將{% url mobile_member_detail order.id %}去掉,不然運(yùn)行時(shí)會(huì)報(bào)錯(cuò)。前端頁(yè)面要顯示訂單編號(hào)同時(shí)還要顯示訂單狀態(tài),這些直接在后端打包傳過來的數(shù)據(jù)中拿就可以了。 <p><b>訂單編號(hào):</b>{{ order.id }}<span>({{ order.statusinfo }})</span></p>中的order.statusinfo是不是很熟悉呀,沒錯(cuò),就是在后端運(yùn)用列表等基本的語(yǔ)法規(guī)則將數(shù)據(jù)庫(kù)中的status改為了文字形式。
遍歷了訂單還不夠,因?yàn)橐粋€(gè)訂單中會(huì)有多個(gè)餐品,咱們還需要將餐品詳情也都遍歷出來,循環(huán)控制語(yǔ)句解決了這個(gè)問題。在訂單頁(yè),這次設(shè)計(jì)的只是展示每個(gè)訂單餐品的圖片,在數(shù)據(jù)庫(kù)中獲取到圖片的名字,然后在對(duì)應(yīng)的目錄下將圖片取出來就可以了,代碼: <img src="{% static uploads/product/ %}{{ vo.product.cover_pic }}" alt="">
訂單總價(jià)和下單時(shí)間在數(shù)據(jù)庫(kù)中都有,直接取出來就可以。"我的訂單"列表頁(yè)是不是很簡(jiǎn)單呢!
繼續(xù)往下寫,在訂單列表,點(diǎn)擊某一訂單能跳到訂單詳情頁(yè)就好了。這個(gè)功能可以實(shí)現(xiàn),來梳理下邏輯。
def detail(request,uid): 瀏覽會(huì)員訂單詳情 order = Orders.objects.get(id=uid) order_status = ["無","排隊(duì)中","已撤銷","已完成"] #獲取關(guān)聯(lián)其他表數(shù)據(jù)(訂單詳情,店鋪信息) plist = OrderDetail.objects.filter(order_id=order.id) order.plist = plist shop = Shop.objects.only("name").get(id=order.shop_id) order.shopname = shop.name order.statusinfo = order_status[order.status] # 轉(zhuǎn)換訂單狀態(tài) return render(request, "mobile/member-detail.html", {"order":order})以上是訂單詳情頁(yè)的后端代碼邏輯。當(dāng)用戶點(diǎn)擊某一訂單時(shí),會(huì)獲取到該訂單的id號(hào),通過前端傳過來的id號(hào)獲取該訂單的信息,然后通過訂單id號(hào)匹配到對(duì)應(yīng)的訂單詳情數(shù)據(jù),通過訂單表中的商鋪id獲取對(duì)應(yīng)的商鋪名稱,并將訂單詳情數(shù)據(jù)、商鋪名稱都打包到order中。訂單狀態(tài)這塊的邏輯是不是很熟悉,和剛才訂單列表頁(yè)的訂單狀態(tài)邏輯一樣。
說完了后端,現(xiàn)在開始看下前端的實(shí)現(xiàn)。
{% extends mobile/base.html %}
{% load static %}
{% block mainbody %}
<body ontouchstart="return true;">
<!--頭部-->
<header>
<div class="header">
<h1>訂單詳情</h1>
<a href="{% url mobile_member_orders %}" class="return"><i></i></a>
</div>
</header>
<!--內(nèi)容區(qū)-->
<article class="main-container">
<!--訂單編號(hào)-->
<div class="memberDetailheader line">訂單號(hào):{{ order.id }}{{ order.statusinfo }}</div>
<!--購(gòu)買商品-->
<div class="list-content cartlist order-Pro memberDetaillist">
<ul class="line-li">
{% for vo in order.plist %}
<li>
<a href="#"><div class="pro-img">
<img src="{% static uploads/product/ %}{{ vo.product.cover_pic }}" alt=""></div></a>
<div class="pro-con"><h3>{{ vo.product_name }}</h3><b>{{ vo.price }}元</b><p>X{{ vo.quantity }}</p></div>
</li>
{% endfor %}
</ul>
</div>
<!--價(jià)格、下單時(shí)間-->
<div class="memberDetailPrice line">
<p>共計(jì):{{ order.plist|length }} 個(gè) 金額:{{ order.money }}元</p>
<p style="font-size: 13px;">
下單時(shí)間:{{ order.create_at|date:Y-m-d H:i }}<br/>
{{ order.shopname }}
</p>
</div>
</article>
</body>
{% endblock %}
前端主要是將后端的數(shù)據(jù)再遍歷出來,訂單詳情頁(yè)的代碼邏輯和訂單列表的邏輯差不多,這里不做過多詳細(xì)解釋。order.plist|length這塊特別說明下,后端里order.plist是對(duì)應(yīng)的該訂單下訂單詳情里的訂餐數(shù)據(jù),length指的是訂單詳情表里有多少個(gè)該訂單對(duì)應(yīng)的餐品,是做統(tǒng)計(jì)用的。
前面已經(jīng)說了個(gè)人中心模塊的訂單列表和訂單詳情頁(yè),接下來說一下一個(gè)非常簡(jiǎn)單的邏輯:退出?,F(xiàn)在想一下,何為退出呢?就是將緩存的用戶信息清除,跳到登錄頁(yè)面唄。對(duì),就是這樣做的。這塊邏輯主要是在后端,后端的實(shí)現(xiàn)也非常簡(jiǎn)單。
def logout(request): 執(zhí)行會(huì)員退出 del request.session[mobileuser] return render(request, mobile/register.html)這里注意下,清除要用del。我在調(diào)試這段代碼時(shí)用了request.session[mobileuser] = {},結(jié)果沒有達(dá)到預(yù)期結(jié)果?,F(xiàn)在復(fù)盤,應(yīng)該是將該用戶緩存信息置為空,說明該用戶緩存信息只是為空了,還是存在該用戶信息的,所以出現(xiàn)了一系列bug。而將用戶緩存信息del,說明該用戶的信息已經(jīng)被清除了,緩存信息沒有了,頁(yè)面自然跳轉(zhuǎn)到登錄頁(yè)面。
現(xiàn)在個(gè)人中心還有我的資料、修改密碼、收貨地址等功能需要實(shí)現(xiàn),因?yàn)闀r(shí)間關(guān)系就不一一實(shí)現(xiàn)了。等有時(shí)間了我再去一一實(shí)現(xiàn)這些功能,有興趣的同學(xué)可以嘗試實(shí)現(xiàn)下,下一章節(jié)開始講大堂點(diǎn)餐功能
#頭條創(chuàng)作挑戰(zhàn)賽#
以上就是【大部分人都認(rèn)可!萬萬沒想到(關(guān)于plc的畢業(yè)設(shè)計(jì)論文)關(guān)于plc的畢業(yè)論文題目簡(jiǎn)單-基于Django+mysql的點(diǎn)餐系統(tǒng)設(shè)計(jì)-第十三篇(H5點(diǎn)餐:訂單的展示)】的全部?jī)?nèi)容。


評(píng)論