加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

day85:luffy:购物车根据有效期不同切换价格&购物车删除操作&

发布时间:2020-12-20 09:59:47 所属栏目:Python 来源:网络整理
导读:目录 1.购物车有效期切换 2.根据有效期不同切换价格 3.购物车删除操作 4.价格结算 5.订单页面-初始化 1.购物车有效期切换 1.关于有效期表结构的设计 1.course/models.py class CourseExpire(BaseModel): """ 课程有效期模型 """ # 后面可以在数据库把course

目录

1.购物车有效期切换

2.根据有效期不同切换价格

3.购物车删除操作

4.价格结算

5.订单页面-初始化

1.购物车有效期切换

1.关于有效期表结构的设计

1.course/models.py

class CourseExpire(BaseModel):
    """课程有效期模型"""
    # 后面可以在数据库把course和expire_time字段设置为联合索引
    course = models.ForeignKey("Course",related_name='course_expire',on_delete=models.CASCADE,verbose_name=课程名称")

     有效期限,天数
    expire_time = models.IntegerField(verbose_name=有效期有效期按天数计算 一个月有效等等
    expire_text = models.CharField(max_length=150,1)">提示文本True)
     每个有效期的价格
    price = models.DecimalField(max_digits=6,decimal_places=2,1)">课程价格0)

     Meta:
        db_table = ly_course_expire
        verbose_name = 课程有效期
        verbose_name_plural = verbose_name

    def __str__(self):
        return 课程:%s,有效期:%s,价格:%s" % (self.course,self.expire_text,self.price)
课程有效期表结构设计

在course表中的price字段加一个提示文本

price = models.DecimalField(max_digits=6,1)">课程原价如果填写的价格为0,那么表示当前课程在购买的时候,没有永久有效的期限。')

2.插入一些测试数据

INSERT INTO `ly_course_expire`
(`id`,`orders`,`is_show`,`is_deleted`,`created_time`,`updated_time`,`expire_time`,`expire_text`,`course_id`,`price`)
VALUES
(1,0,'2019-08-19 02:05:22.3688232019-08-19 02:05:22.36885530,1)">一个月有效398.00),(2,1)">2019-08-19 02:05:37.3972052019-08-19 02:05:37.39723360,1)">2个月有效588.003,1)">2019-08-19 02:05:57.0294112019-08-19 02:05:57.029440180,1)">半年内有效1000.004,1)">2019-08-19 02:07:29.0666172019-08-19 02:08:29.1567303天内有效0.885,1)">2019-08-19 02:07:46.1208272019-08-19 02:08:18.6524521个月有效188.006,1)">2019-08-19 02:07:59.8764212019-08-19 02:07:59.876454298.00);

3.xadmin注册

course/adminx.py

from .models import CourseExpire
 CourseExpireModelAdmin(object):
    商品有效期模型pass
xadmin.site.register(CourseExpire,CourseExpireModelAdmin)

2.课程有效期-后端接口

course/models.py

 Course:    
     获取课程有效期
    def get_expire(self):
        
         课程表和课程有效期表时一对多的关系 反向查询
        expire_list = self.course_expire.all()  查询到当前课程所拥有的有效期种类
        data = []
        for expire in expire_list:
            data.append({
                id':expire.id,expire_text':expire.expire_text, 有效期的那个文本 比如'三个月有效'
                price':expire.price,1)"> 有效期对应的价格
            })

         当价格为0时,没有永久有效这一项,其他的都有
        if self.price > 0:
            data.append({
                : 0,1)">': 永久有效,1)">: self.price,})

        return data

cart/views.py

 AddCartView(ViewSet):

     cart_list(self,request):
          
        try:
            ......
            cart_data_list.append({
               ......
                expire_list:course_obj.get_expire(),......
            })
        except Exception:
           ......
        return Response({msg':xxxcart_data_list':cart_data_list})

3.课程有效期-前端

cartitem.vue

<div ="cart_column column_3">
    el-select v-model="cart.expire_id" size="mini" placeholder="请选择购买有效期" class="my_el_select">
        el-option :label="expire.expire_text" :value="expire.id" :key v-for="(expire,expire_index) in cart.expire_list"></el-option</el-select>
div>

2.根据有效期不同切换价格

1.有效期切换更改redis中数据

cart/views.py

 AddCartView:
         change_expire(self,request):

            user_id = request.user.id
            course_id = request.data.get(course_id)
            expire_id = request.data.get(expire_id)
            
            检验课程id是否有效
            :
                course_obj = models.Course.objects.get(id=course_id)
            :
                课程不存在'},status=status.HTTP_400_BAD_REQUEST)
             检验有效期id是否有效
            if expire_id > 0:
                 expire_object = models.CourseExpire.objects.get(id=expire_id)
            课程有效期不存在status.HTTP_400_BAD_REQUEST)

             计算xx课程xx有效期的真实价格
            real_price = course_obj.real_price(expire_id)

             更改了新的有效期,要将更改之后的有效期存放到redis中
            conn = get_redis_connection(cart)
            conn.hset(cart_%s' % user_id,course_id,expire_id)

            切换成功!real_price': real_price})

cart/urls.py

urlpatterns = [
    ......
    path(expires/putchange_expire}))
]

2.有效期切换让页面价格变化

course/models.py

 Course:
        def real_price(self,expire_id=0):  增加expire_id=0参数 让真实价格根据不同的有效期显示不同的价格
            price = float(self.price)
            '''
            1.如果不是永久有效(expire_id>0),那就从course_expire获取该有效期对应的价格
            2.如果是永久有效(expire_id=0),那么真实价格就等于它原来的价格
            '''
             0:
                expire_obj = self.course_expire.get(id=expire_id)
                price = float(expire_obj.price)

            r_price = price
            a = self.activity()
            if a:
                sale = a[0].discount.sale
                condition_price = a[0].discount.condition

                 限时免费
                if not sale.strip():
                    r_price = 0

                 限时折扣  *0.5
                elif *'  sale.strip():
                    if price >= condition_price:
                        _,d = sale.split()
                        r_price = price * float(d)
                 限时减免  -100
                elif sale.strip().startswith(-):
                    )
                        r_price = price - float(d)

                 sale:
                     condition_price:
                        l1 = sale.split(rn)
                        dis_list = []  10 50  25
                        for i  l1:
                            a,b = i[1:].split()

                            400
                             float(a):
                                dis_list.append(float(b))

                        max_dis = max(dis_list)
                        r_price = price - max_dis

            return r_price

cartitem.vue

// js
 watch:{
      ......
       当用户选择的课程有效期发生变化时(在前端下拉框选择了别的有效期)
      'cart.expire_id':function (){
        let token = localStorage.token || sessionStorage.token;

          this.$axios.put(`${this.$settings.Host}/cart/expires/`,{
             将课程id和课程对应的有效期id提交到后端
            course_id: this.cart.course_id,expire_id:.cart.expire_id,},{
            headers:{
              'Authorization':'jwt ' + token
            }

      }
      ).then((res)=>{
        .$message.success(res.data.msg);
              
         修改有效期成功,将真实价格返回给前端
        this.cart.real_price = res.data.real_price;
              
        this.$emit('change_expire_handler'catch((error)=>{
            .$message.error(error.response.data.msg)
          })
    }
},

cart.vue

="cart_course_list"CartItem v-for="(value,index) in cart_data_list"="index" :cart="value" @cal_t_p="cal_total_price" @change_expire_handler @delete_course_handler="delete_c(index)"CartItem>

>

3.页面刷新 应该重置有效期

cart/views.py

 AddCartView:
     request.user.id

        conn = get_redis_connection()

        conn.delete(selected_cart_%s user_id)
        ret = conn.hgetall(' % user_id)  dict {b'1': b'0',b'2': b'0'}
        cart_data_list = []

        :
            for cid,eid  ret.items():
                course_id = cid.decode(utf-8)
                
                 当用户查看购物车页面时->默认显示永久有效
                conn.hset( 0
                
                course_obj = models.Course.objects.get(id=course_id)

                cart_data_list.append({
                    :course_obj.id,1)">name:course_obj.name,1)">course_img':contains.SERVER_ADDR + course_obj.course_img.url,1)">:course_obj.price,1)">:course_obj.real_price(),1)">:expire_id,1)">selected':False,1)"> 默认没有勾选
                })
         Exception:
            logger.error(获取购物车数据失败)
            后台数据库出问题了,请联系管理员status.HTTP_507_INSUFFICIENT_STORAGE)

        :cart_data_list})
    

3.购物车删除操作

cartitem.vue

="cart_column column_4" id="delete" @click="delete_course">删除>
delete_course(){
        let token = localStorage.token ||this.$axios.delete(`${this.$settings.Host}/cart/add_cart/`,{
            params:{
              course_id: this.cart.course_id,1)"> request.query_params.get('course_id')
            },headers:{
              'Authorization':'jwt ' + token
            }
          })
        .then((res)=>{
          .$message.success(res.data.msg);
              
           当用户要删除购物车中的某条课程记录时 执行Cart父组件的删除课程事件
          this.$emit('delete_course_handler')
        })
        ..$message.error(error.response.data.msg);
        })
      }

1.后端redis删除

cart/urls.py

urlpatterns = [
    path(add_cart/postaddgetcart_listpatchchange_selectcancel_selectdeletedelete_course
         })),path(}))

]

cart/views.py

 delete_course(self,request):
        user_id = request.user.id
        course_id = request.query_params.get()
        
        conn = get_redis_connection()
        pipe = conn.pipeline()
        pipe.hdel(删除成功'})

2.前端同步实现删除效果

用户删除一条购物车数据 后端已经删除了 但是前端页面也要同步删除

Cart.vue

delete_c(index){
        this.cart_data_list.splice(index,1)
        this.cal_total_price()  删除之后 重新触发计算总价格的方法
      }

Cartitem.vue

 token
            }
          })
        .then((res)=>{  删除时 触发Cart父组件的删除事件
          .$message.success(res.data.msg);
          .$message.error(error.response.data.msg);
        })
      }
  }

4.价格结算

1.价格结算页面-准备工作

1.结算初始页面

<!-- 结算页面初始界面 -->

2.配置路由

index.js

import Vue from 'vue'
import Order from "@/components/Order"

Vue.use(Router)
export default new Router({
  mode:'history'

3.点击去结算按钮 看到页面

cart.vue

span ="goto_pay"><router-link to="/order/">去结算router-linkspan>          

2.价格结算页面-后端

cart/urls.py

urlpatterns = [
    ...
    path(show_pay_info show_pay_info(self,request):
    
    user_id = request.user.id
    
    conn = get_redis_connection()
    
     获取用户购物车选中的所有课程id
    select_list = conn.smembers( user_id)
    data = []

     获取用户购物车的课程id:有效期id
    ret = conn.hgetall( dict {b'1': b'0',b'2': b'0'}

    
     ret.items():
        expire_id = int(eid.decode())
        if cid in select_list:  如果课程是被勾选的

            course_id = int(cid.decode())
             获取这个'被勾选的课程'model对象
            course_obj = models.Course.objects.get(id=course_id)
           
             如果课程的有效期不是永久有效
             0:
                expire_obj = models.CourseExpire.objects.get(id=expire_id)
                data.append({
                    :course_obj.real_price(expire_id),1)">:expire_obj.expire_text,})
                
             如果课程的有效期是永久有效
            else:
                data.append({
                    : course_obj.id,1)">: course_obj.name,1)">': contains.SERVER_ADDR +: course_obj.real_price(expire_id),})


    data':data})

3.价格结算页面-前端

order.vue

methods: {
      get_order_data(){
        let token = localStorage.token || sessionStorage.token;
        this.$axios.get(`${          headers:{
              'Authorization':'jwt ' + token
            }
        }).then((res)=>this.course_list = res.data.data;
        })
      },
 html --> 
="cart-item"="(course,index) in course_list">
          el-row>
             el-col :span="2"="checkbox">&nbsp;&nbsp;el-col="10"="course-info">
               img :src="course.course_img" alt="">
                >{{course.name}}="8">{{course.expire_text}}="4"="course-price">¥{{course.real_price}}>
           >

4.切换支付方式-微信/支付宝

其实就是几张图片 点击显示图片而已

Order.vue

="alipay"  v-if="pay_type===1"src="../../static/img/alipay2.png"  alt="pay_type=1"  v-else="../../static/img/alipay.png"="alipay wechat" v-if="pay_type===2"="../../static/img/wechat2.png"=""   @click="pay_type=2" v-else="../../static/img/wechat.png">

5.订单页面-初始化

order/models.py

from django.db  models

 Create your models here.


from lyapi.utils.models  BaseModel
from users.models  User
from course.models  Course
 Order(BaseModel):
    订单模型"""
    status_choices = (
        (0,1)">未支付已支付已取消超时取消支付宝微信支付订单标题)
    total_price = models.DecimalField(max_digits=6,1)">订单总价0)
    real_price = models.DecimalField(max_digits=6,1)">实付金额0)
    order_number = models.CharField(max_length=64,1)">订单号)
    order_status = models.SmallIntegerField(choices=status_choices,1)">订单状态)
    pay_type = models.SmallIntegerField(choices=pay_choices,default=1,1)">支付方式)
    credit = models.IntegerField(default=0,1)">使用的积分数量)
    coupon = models.IntegerField(null=True,1)">用户优惠券ID)
    order_desc = models.TextField(max_length=500,1)">订单描述True)
    pay_time = models.DateTimeField(null=True,1)">支付时间)
    user = models.ForeignKey(User,1)">user_orders下单用户 Meta:
        db_table=ly_order
        verbose_name= 订单记录
        verbose_name_plural= "

    %s,总价: %s,实付: %s" % (self.order_title,self.total_price,self.real_price)


 OrderDetail(BaseModel):
    
    订单详情
    
    order = models.ForeignKey(Order,1)">order_courses订单ID)
    course = models.ForeignKey(Course,1)">course_orders课程ID)
    expire = models.IntegerField(default=0有效期周期0表示永久有效)
    price = models.DecimalField(max_digits=6,1)">)
    real_price = models.DecimalField(max_digits=6,1)">课程实价)
    discount_name = models.CharField(max_length=120,default="",1)">优惠类型ly_order_detail订单详情%s" % (self.course.name)
订单表结构设计

order/adminx.py

 xadmin
 Order
 OrderModelAdmin(object):
    订单模型管理类

xadmin.site.register(Order,OrderModelAdmin)


 OrderDetail
 OrderDetailModelAdmin(object):
    订单详情模型管理类

xadmin.site.register(OrderDetail,OrderDetailModelAdmin)

order/__init__.py

default_app_config = order.apps.OrderConfig"

order/app.py

from django.apps  AppConfig


 OrderConfig(AppConfig):
    name = order
    verbose_name = 订单管理'

order/urls.py

from django.urls  path,re_path
from .  views

urlpatterns =add_money/
from django.shortcuts  render
from rest_framework.generics  CreateAPIView
 Create your views here.
 models
from .serializers  OrderModelSerializer
from rest_framework.permissions  IsAuthenticated

 OrderView(CreateAPIView):
    queryset = models.Order.objects.filter(is_deleted=False,is_show=True)
    serializer_class = OrderModelSerializer
    permission_classes = [IsAuthenticated,]

order/serializers.py

 datetime
from rest_framework  serializers
from django_redis  get_redis_connection
 transaction


 OrderModelSerializer(serializers.ModelSerializer):
     Meta:
        model = models.Order
        fields = [order_numberpay_typecouponcredit]
        
        
        1.用户在订单页面需要提交过来的数据:
            支付类型:微信/支付宝
            优惠券
            积分
        2.用户提交数据成功后,前端页面需要返回过来的数据:
            id
            订单号
        '''
        extra_kwargs = {
            ':{read_only:True},1)">write_only validate(self,attrs):

         获取用户使用的支付方式
        pay_type = int(attrs.get(#
        
         验证用户使用的支付方式是否是支付宝或微信中的一种
        if pay_type not in [i[0]  models.Order.pay_choices]:
            raise serializers.ValidationError(支付方式不对!)

            
         todo 优惠券校验,看看是否过期了等等


         todo 积分上限校验

        return attrs

     create(self,validated_data):
         生成订单号  [日期,用户id,自增数据]
            current_time = datetime.datetime.now()
            now = current_time.strftime(%Y%m%d%H%M%S)
            user_id = self.context[request].user.id
            
            conn = get_redis_connection()
            num = conn.incr(num)
            
             生成一个唯一的订单号
            order_number = now + %06d" % user_id +  num

            with transaction.atomic():   添加事务

                 生成订单
                order_obj = models.Order.objects.create(**{
                    order_title31期订单total_price: order_number,1)">order_status': validated_data.get(order_desc女朋友pay_time: current_time,1)">user_id: user_id, 'user':user_obj,
                })

                select_list = conn.smembers( user_id)

                ret = conn.hgetall( ret.items():
                    expire_id = int(eid.decode())
                     select_list:

                        course_id = int(cid.decode())
                        course_obj = Course.objects.get(id=course_id)
                         0:
                            expire_text = CourseExpire.objects.get(id=expire_id).expire_text

                         生成订单详情
                        models.OrderDetail.objects.create(**{
                            : order_obj,1)">course: course_obj,1)">expire: expire_id,1)">: course_obj.price,1)">discount_name: course_obj.discount_name(),})
             print('xxxxx')
         Exception:
            raise models.Order.DoesNotExist

        return order_obj

?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读