订单页面

在前面我们已经构建了,购物车的页面,接下来到了结算页面

1.首先,在购物车页面点击去结算按钮时,我们需要做如下动作

.前端发送生成订单的请求,点击标签内触发事件 create_order

template:去结算script,methods中:

create_order(){//生成订单

this.$axios.post("http://127.0.0.1:8000/orders/",{},{

headers: {//附带已经登录用户的jwt token 提供给后端,一定不能疏忽这个空格'Authorization': 'JWT' +this.token

},

responseType:"json",

}).then(response=>{//在session中保存订单ID,便于在结算页面发送请求时带上order_id,查询订单详情

sessionStorage.order_id=response.data.order_id;//跳转到结算页面

this.$router.push("/order")

}).catch(error=>{//生成订单失败

alert("生成订单失败")

})

后端需要对该请求作出处理,将订单保存到mysql中,并返回对应的订单的ID值(不是订单号),但是在做订单保存之前,我们必须先创建订单的数据模型,其中模型如下所示

order.models:

订单的模型:

#Create your models here.

from django.db importmodels#Create your models here.

from luffy.apps.user.models importUserfrom luffy.apps.courses.models importCourseclassOrder(models.Model):"""订单记录"""status_choices=(

(0,'未支付'),

(1, '已支付'),

(2, '已取消'),

)

total_price= models.DecimalField(max_digits=10, decimal_places=2, verbose_name="订单总价", default=0)

order_number= models.CharField(max_length=32,verbose_name="订单号")

order_status= models.SmallIntegerField(choices=status_choices, default=0, verbose_name="订单状态")

order_desc= models.CharField(max_length=120,verbose_name="订单描述")

created_time= models.DateTimeField(verbose_name="订单生成时间", auto_now_add=True)

pay_time= models.DateTimeField(verbose_name="订单支付时间", auto_now_add=True)

user= models.ForeignKey(User, related_name='user_orders', on_delete=models.DO_NOTHING,verbose_name="用户ID")classMeta:

db_table="ly_order"verbose_name= "订单记录"verbose_name_plural= "订单记录"

classOrderDetail(models.Model):"""订单详情"""order= models.ForeignKey("Order", related_name='order_course', on_delete=models.CASCADE, verbose_name="订单ID")

course= models.ForeignKey(Course, related_name='course_order', on_delete=models.CASCADE, verbose_name="课程ID")

user= models.ForeignKey(User, null=True, related_name="course", on_delete=models.DO_NOTHING, verbose_name="用户ID")

unit_price= models.DecimalField(max_digits=8, decimal_places=2, null=True, verbose_name="课程价格")classMeta:

db_table="ly_order_detail"verbose_name= "订单详情"verbose_name_plural= "订单详情"

而后端的处理代码如下所示

classOrderAPIView(APIView):defpost(self,request):#获取用户ID

try:

user_id=request.user.idexcept:return Response({"message": "用户不存在!"})#自己生成一个订单号,# 结合时间戳和当前用户ID来生成,才能保证整站唯一

order_number = datetime.now().strftime("%Y%m%d%H%M%S") + "%07d" % int(user_id) + "%04d" % random.randint(0,9999)#从redis中获取商品信息[先获取勾选集,然后根据勾选集,到购物车中查询对应的商品价格]

redis = get_redis_connection("cart")

course_id_list= redis.smembers("cart_select_%s" %user_id)#计算总价格

total_price =0

cart_info= redis.hgetall("cart_%s" % user_id) #返回哈希数据中的键值对

for course_id,course_price incart_info.items():if course_id incourse_id_list:

total_price+=Decimal(course_price.decode())#创建订单数据

order =Order.objects.create(

user_id=user_id,

order_number=order_number,

order_status= 0, #订单状态默认为未支付

order_desc = "路飞学成课程购买", ## 订单描述信息

total_price =total_price

)#返回响应信息给客户端

print("order",order)print("order_type", type(order))iforder:for course_id incourse_id_list:#记录订单相关的课程信息到订单详情

OrderDetail.objects.create(

course_id=course_id,

order_id=order.id,

user_id=user_id,

unit_price= redis.hget("cart_%s" %user_id, course_id).decode(),

)#删除redis中已经生成订单的商品信息

redis.hdel("cart_%s" %user_id, course_id.decode())

redis.srem("cart_select_%s" %user_id, course_id.decode())return Response({"order_id": order.id}, status=status.HTTP_200_OK)else:return Response({"message": "生成订单失败!"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

2.在1步骤完成后,前端会跳转到order页面,在加载order页面,我们需要将order页面的数据加载过来,需要发送请求

created() {//判断用户是否已经登陆了。if( !this.token){

this.$router.push("/login");

}

let _this=this;//发起请求获取购物车中的商品信息,_this.order_id时在cart发送创建订单请求返回数据时,保存在session中的订单ID

_this.$axios.get("http://127.0.0.1:8000/orders/detail/"+_this.order_id,{

headers: {'Authorization': 'JWT' +_this.token

},

responseType:'json',

}).then(response=>{

console.log("response.data",response.data)

_this.course_list=response.data.order_course;

_this.total=response.data.total_price

})

当前端发送请求后,我们需要在后端作出处理来响应请求,返回对应订单的数据

order/views

classOrderDetailAPIView(APIView):defget(self,request,order_id):"""显示订单中的商品信息"""

try:

order= Order.objects.get(pk=order_id)exceptOrder.DoesNotExist():return Response({"message":"当前订单不存在!"},status=status.HTTP_400_BAD_REQUEST)

seriazlier= OrderSerializer(instance=order)return Response(seriazlier.data,status=status.HTTP_200_OK)

其中使用了序列化器:

from rest_framework importserializersfrom .models importOrder,OrderDetailfrom courses.models importCourseclassCourseSerializer(serializers.ModelSerializer):classMeta:

model=Course

fields= ("course_http_img","name")classOrderDetailSerializer(serializers.ModelSerializer):

course=CourseSerializer()classMeta:

model=OrderDetail

fields= ("course","unit_price")classOrderSerializer(serializers.ModelSerializer):

order_course= OrderDetailSerializer(many=True)classMeta:

model=Order

fields= ("id","total_price","order_course")

可以看到上面代码的序列化器中,有些字段嵌套了三层,

order_course   ==>   order_course = OrderDetailSerializer(many=True)  ==>   course = CourseSerializer()

注意:在CourseSerializer这个序列化器中,

class CourseSerializer(serializers.ModelSerializer):

class Meta:

model = Course

fields = ("course_http_img","name")

字段 course_http_img 原本是不在模型表中的,是我们自定义的一个字段,需要在对应的models中,做出定义,如下代码

courses/models:

classCourse(models.Model):

.....#自定义显示字段

defcourse_http_img(self):return settings.HOST + self.course_img.url

3.前端接收到后端返回的数据,进行数据渲染即可

完整前后端代码如下:

order.vue:

1

2

3

4

5

购物车结算 共1门课程

6

7

8

9 课程

10 有效期

11 价格

12

13

14

15

16

17

18

19 {{item.course.name}}

20

21 永久有效

22 ¥{{item.unit_price}}

23

24

25

26

27 支付方式:

28

29 实付款: ¥{{total}}

30 支付宝支付

31

32

33

34

35

36

37

38

39 import Header from "./common/Header"

40 import Footer from "./common/Footer"

41

42 export default{43 name:"Order",44 data(){45 return{46 total:0,47 course_list:[],48 token: localStorage.token ||sessionStorage.token,49 id : localStorage.id ||sessionStorage.id,50 order_id:sessionStorage.order_id || null,51 }52 },53

54 components:{55 Header,56 Footer,57

58 },59 methods:{60

61 },62 created() {63 //判断用户是否已经登陆了。

64 if( !this.token){65 this.$router.push("/login");66 }67

68 let _this = this;69 //发起请求获取购物车中的商品信息

70 _this.$axios.get("http://127.0.0.1:8000/orders/detail/"+_this.order_id,{71 headers: {72 'Authorization': 'JWT ' +_this.token73 },74 responseType: 'json',75 }).then(response=>{76 console.log("response.data",response.data)77 _this.course_list =response.data.order_course;78 _this.total =response.data.total_price79

80 })81 },82 }83

84

85

86

87 .cart{88 margin-top: 80px;89 }90 .cart-info{91 overflow: hidden;92 width: 1200px;93 margin: auto;94 }95 .cart-top{96 font-size: 18px;97 color: #666;98 margin: 25px 0;99 font-weight: normal;100 }101 .cart-top span{102 font-size: 12px;103 color: #d0d0d0;104 display: inline-block;105 }106 .cart-title{107 background: #F7F7F7;108 height: 70px;109 }110 .calc{111 margin-top: 25px;112 margin-bottom: 40px;113 }114

115 .calc .count{116 text-align: right;117 margin-right: 10px;118 vertical-align: middle;119 }120 .calc .count span{121 font-size: 36px;122 color: #333;123 }124 .calc .cart-pay{125 margin-top: 5px;126 width: 110px;127 height: 38px;128 outline: none;129 border: none;130 color: #fff;131 line-height: 38px;132 background: #ffc210;133 border-radius: 4px;134 font-size: 16px;135 text-align: center;136 cursor: pointer;137 }138 .cart-item{139 height: 120px;140 line-height: 120px;141 }142 .course-info img{143 width: 175px;144 height: 115px;145 margin-right: 35px;146 vertical-align: middle;147 }148 .alipay{149 display: block;150 height: 48px;151 }152 .alipay img{153 height: 100%;154 width:auto;155 }156

157 .pay-text{158 display: block;159 text-align: right;160 height: 100%;161 line-height: 100%;162 vertical-align: middle;163 margin-top: 20px;164 }165

View Code

order.views:

1 importrandom2 from datetime importdatetime3 from decimal importDecimal4 from django_redis importget_redis_connection5 from rest_framework importstatus6 from rest_framework.response importResponse7 from rest_framework.views importAPIView8

9 from luffy.apps.orders.models importOrder, OrderDetail10 from luffy.apps.orders.serializers importOrderSerializer11

12

13 classOrderAPIView(APIView):14 defget(self,request):15 #获取用户ID

16 user_id =request.user.id17

18 return Response({"message":"ok"})19 defpost(self,request):20 #获取用户ID

21 try:22 user_id =request.user.id23 except:24 return Response({"message": "用户不存在!"})25

26 #自己生成一个订单号,# 结合时间戳和当前用户ID来生成,才能保证整站唯一

27 order_number = datetime.now().strftime("%Y%m%d%H%M%S") + "%07d" % int(user_id) + "%04d" % random.randint(0,9999)28 #从redis中获取商品信息[先获取勾选集,然后根据勾选集,到购物车中查询对应的商品价格]

29 redis = get_redis_connection("cart")30 course_id_list = redis.smembers("cart_select_%s" %user_id)31 #计算总价格

32 total_price =033 cart_info = redis.hgetall("cart_%s" % user_id) #返回哈希数据中的键值对

34 for course_id,course_price incart_info.items():35 if course_id incourse_id_list:36 total_price +=Decimal(course_price.decode())37 #创建订单数据

38 order =Order.objects.create(39 user_id =user_id,40 order_number =order_number,41 order_status = 0, #订单状态默认为未支付

42 order_desc = "路飞学成课程购买", ## 订单描述信息

43 total_price =total_price44 )45 #返回响应信息给客户端

46 print("order",order)47 print("order_type", type(order))48 iforder:49 for course_id incourse_id_list:50 #记录订单相关的课程信息到订单详情

51 OrderDetail.objects.create(52 course_id =course_id,53 order_id =order.id,54 user_id =user_id,55 unit_price = redis.hget("cart_%s" %user_id, course_id).decode(),56 )57 #删除redis中已经生成订单的商品信息

58 redis.hdel("cart_%s" %user_id, course_id.decode())59 redis.srem("cart_select_%s" %user_id, course_id.decode())60

61 return Response({"order_id": order.id}, status=status.HTTP_200_OK)62 else:63 return Response({"message": "生成订单失败!"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)64

65

66 classOrderDetailAPIView(APIView):67 defget(self,request,order_id):68 """显示订单中的商品信息"""

69 try:70 order = Order.objects.get(pk=order_id)71 exceptOrder.DoesNotExist():72 return Response({"message":"当前订单不存在!"},status=status.HTTP_400_BAD_REQUEST)73

74 seriazlier = OrderSerializer(instance=order)75 return Response(seriazlier.data,status=status.HTTP_200_OK)

View Code

order/serializer:

1 from rest_framework importserializers2

3 from luffy.apps.courses.models importCourse4 from luffy.apps.orders.models importOrder, OrderDetail5

6 classCourseDetailSerializer(serializers.ModelSerializer):7 classMeta:8 model =Course9 fields=("course_http_img","name")10

11 classOrderDetailSerializer(serializers.ModelSerializer):12 course =CourseDetailSerializer()13 classMeta:14 model =OrderDetail15 fields=("unit_price","course")16

17 classOrderSerializer(serializers.ModelSerializer):18 order_course = OrderDetailSerializer(many=True)19 classMeta:20 model =Order21 fields=("id","total_price","order_course")

View Code

mysql结算订单表到用户_Luffy之结算订单页面(订单模型表的创建,订单的生成,以及订单详情展示等)...相关推荐

  1. php json连表,tabulator - 从包含JSON的PHP页面填充Tabulator表 - SO中文参考 - www.soinside.com...

    我是编程和制表师的新手.我有一个显示我的JSON结果的PHP页面.我只想在不同页面上的制表表中查看此结果. JSON结果的格式如下,它位于名为proxystatus.php的页面上. { " ...

  2. HTML 表格标签、列表标签、表单标签(案例: 注册页面)

    1. 表格标签 表格是实际开发中非常常用的标签: 1. 表格的主要作用 2. 表格的基本语法 1.1 表格的主要作用 表格主要用于显示.展示数据,因为它可以让数据显示的非常的规整,可读性非常好.特别是 ...

  3. mysql 多维度分表_亿级订单数据分库分表设计方案(满足多维度查询:订单号、用户、商家、渠道)...

    根据业务初步预估订单业务量,每天500万的数据.我们将订单数据划分为了2大类型:分别为热数据和冷数据. 热数据:1个月内的订单数据,查询实时性较高; 冷数据:归档订单数据,查询频率不高; 根据实际业务 ...

  4. mysql查询每个用户第一条数据_MySQL数据库订单表按用户邮箱字段分组查询每个用户的第一条记录...

    程序开发或者一些数据统计时,在MySQL中使用GROUP BY分组是很常用的SQL语句.那么,如果如下的简单示例订单数据表,我们现需要使用GROUP BY分组后查询每个用户的第一个订单记录,应该如何实 ...

  5. Mysql —— C语言链接mysql数据库,命令行形式(getopt()函数),用户、用户组增删改查(用户组表内有用户控制的策略字段)

    函数说明--getopt(): 函数说明 getopt()用来分析命令行参数.参数argc和argv分别代表参数个数和内容,跟main()函数的命令行参数是一样的. optstring中的指定的内容的 ...

  6. mysql查询每个id的前10条数据_解决 MySQL 比如我要拉取一个消息表中用户id为1的前10条最新数据...

    我们都知道,各种主流的社交应用或者阅读应用,基本都有列表类视图,并且都有滑到底部加载更多这一功能, 对应后端就是分页拉取数据. 好处不言而喻,一般来说,这些数据项都是按时间倒序排列的,用户只关心最新的 ...

  7. mysql user表修复_Mysql user表root用户误删除后恢复

    mysql user表root 用户误删除后恢复root用户 方法/步骤 1.停止mysql服务:在mysql安装目录下找到my.ini:在my.ini中找到以下片段[mysqld]:另起一行加入代码 ...

  8. mysql用创建的用户登陆并修改表格_MySQL 基础学习二:创建一个用户表,并增删改查...

    MySQL 基础学习二:创建一个用户表,并 增删改查 提示:MySQL 命令建议都用大写,因为小写运行时,还是翻译成大写的. 第一步,创建一个用户表 1,打开控制台,进入数据库 C:\Users\Ad ...

  9. mysql 用户管理表_Mysql—用户表详解(mysql.user)

    MySQL 数据库 Mysql-用户表详解(mysql.user) MySQL是一个多用户管理的数据库,可以为不同用户分配不同的权限,分为root用户和普通用户,root用户为超级管理员,拥有所有权限 ...

最新文章

  1. linux 关闭磁盘检测,linux下检测磁盘状态
  2. JqueryMobile链接一个页面,而链接页面中图片需刷新才显示的问题
  3. JZOJ 5244. 【NOIP2017模拟8.8A组】Daydreamin ' (daydream)
  4. java dwr实现消息推送_dwr消息推送
  5. python定时器库_Python定时器完整示例 python定时器用法举例
  6. ACM题解系列之一:刘汝佳:《算法竞赛入门经典》(第2版)
  7. sql删除主键_产品经理的第一节SQL课——ID到底是干什么的?!
  8. python 字符串replace函数_01-Python里字符串的常用操作方法--replace()函数
  9. SNIFE 和 std::enable_if
  10. python运维开发实战项目-1
  11. STM32单片机全自动锂电池容量电量检测放电电流电池电压ACS712
  12. Windows XP/2000实现自动登陆(加入域和未加域两种情况)
  13. 海尔集团CEO张瑞敏演讲《人不成熟的几大特征》
  14. kettle6.0 连接oracle11g,Kettle表输出报关闭的连接问题的解决方法
  15. WebGL简易教程(十五):加载gltf模型
  16. JDBC中execute、executeQuery和executeUpdate的区别
  17. Android 禁止adb reboot recovery进入recovery模式
  18. prism EventAggregator(事件聚合器)
  19. ORACLE向表插入记录的顺序和读取记录的次序一样吗??
  20. 瓦片地图坐标相关计算

热门文章

  1. vue组件可视化_Vue HTML5音频可视化组件
  2. 做第一批35岁就退休的90后,需要几步?
  3. 联想笔记本加固态后没声音(关于固态那些事)
  4. C++读取通达信shm.tnf文件股票代码/名称
  5. 计算存储分离在京东云消息中间件JCQ上的应用
  6. 运维笔试题1(转载)
  7. phonegap-百度社会化分享-andriod插件-v2.0
  8. 微信小程序单页开发之 min-cli
  9. 局域网搭建IOS应用在线安装环境
  10. 产品回顾本讲谈社汉字学习词典(kald)对于卡西欧EX-字的DataPlus系列