博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vue+django2.0.2-rest-framework 生鲜项目(七)
阅读量:4623 次
发布时间:2019-06-09

本文共 13390 字,大约阅读时间需要 44 分钟。

vue+django2.0.2-rest-framework 生鲜项目


 一、购物车功能

 1、实现购物车获取购物车商品列表信息、添加购物车商品数量、删除购物车商品

1)trade/serializer.py:序列化购物车数据

 几点说明:

  1. serializers.Serializer中没有get(list)、post(create)方法,需要自定义。
  2. views.py中获取当前用户 代码操作:self.request.user  ; serializers.py中,要获取当前用户,代码:self.context["request"].user ,存放于context当中。
  3. goods是一个外键,之前我们序列化goods商品时,goods/serializers.py中有用到序列化的CategorySerializer来展示外键相关信息,一般用list方法访问时使用这种方式展示所需要的详细信息,不需要展示商品详情时不这么做。在购物车model中,因为使用了联合唯一(goods、nums),不允许我们同一个goods+nums添加多个,否则会报错,所以我们不用耦合性较高的ModelSerializers,而是用Serializers。外键处理则使用DRF提供的PrimaryKeyRelatedField字段处理:
    goods = serializers.PrimaryKeyRelatedField(required=True, queryset=Goods.objects.all()) ,
    在serializers.Serializer中,‘queryset=Goods.objects.all()’这句是必须要写的,获取所有的商品数据,是个querysets集合,
    在serializers.ModelSerializer中,该语句是这样:goods = serializers.PrimaryKeyRelatedField(required=True, many=True,read_only),
    两句代码效果是一样的,第二句是因为内部有model,会自己映射,所以不用添加queryset搜查所有数据。
  4. goods = GoodsSerializer():使用序列化这种方式,会将提交的某goods商品所有信息以序列化形式都展示出来,需要全部填写才能提交
    goods = serializers.PrimaryKeyRelatedField:是个querysets集合,只会显示model中(__str__)return的字段信息,比如商品的名称(name),不需要我们操作。
    购物车需要获取的只是goods中的商品名称,故用第二种,不能用第一种序列化的方式。
  5. serializers.Serializer中,create()、update()两个方法,当需要用到时,需要我们在serializers中重载,否则会报错:`create()` must be implemented 。
    而serializers.ModelSerializer中,系统已经简单帮我们实现了这两个方法,不需要我们重载
from .models import ShoppingCartfrom rest_framework import serializersfrom goods.models import Goodsclass ShopCartSerializer(serializers.Serializer):    #获取当前登录的用户    user = serializers.HiddenField(        default=serializers.CurrentUserDefault()    )    nums = serializers.IntegerField(required=True, label="数量",min_value=1,                                    error_messages={                                        "min_value":"商品数量不能小于一",                                        "required": "请选择购买数量"                                    })    #这里是继承Serializer,必须指定queryset对象,如果继承ModelSerializer则不需要指定    #goods是一个外键,可以通过这方法获取goods object中所有的值    goods = serializers.PrimaryKeyRelatedField(required=True, queryset=Goods.objects.all())    #继承的Serializer没有save功能,必须写一个create方法    def create(self, validated_data):        # validated_data是已经处理过的数据        #获取当前用户        # view中:self.request.user;serizlizer中:self.context["request"].user        user = self.context["request"].user        nums = validated_data["nums"]        goods = validated_data["goods"]        existed = ShoppingCart.objects.filter(user=user, goods=goods)        #如果购物车中有记录,数量+nums        #如果购物车车没有记录,就创建        if existed:            existed = existed[0]            existed.nums += nums            existed.save()        else:            #添加到购物车            existed = ShoppingCart.objects.create(**validated_data)        return existed

 2)trade/views.py:

 重载 get_queryset 方法,只查找与当前客户相关的购物车数据

from rest_framework import viewsetsfrom rest_framework.permissions import IsAuthenticatedfrom utils.permissions import IsOwnerOrReadOnlyfrom rest_framework_jwt.authentication import JSONWebTokenAuthenticationfrom rest_framework.authentication import SessionAuthenticationfrom .serializers import ShopCartSerializerfrom .models import ShoppingCartclass ShoppingCartViewset(viewsets.ModelViewSet):    """    购物车功能    list:        获取购物车详情    create:        加入购物车    delete:        删除购物记录    """    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)    serializer_class = ShopCartSerializer    def get_queryset(self):        return ShoppingCart.objects.filter(user=self.request.user)

 

3)urls.py配置:

# 购物车router.register(r'shopcarts', ShoppingCartViewset, base_name="shopcarts")

 

  

 


 

 上述已经完成了当前用户购物车数据获取、购物车商品创建,接下来我们来实现购物车商品数据更新:更新商品数量

  更新数据,需要用到update () 方法,因此,我们需要在serializers中重载该方法:

1)trade/serializer.py下的 ShopCartSerializer 添加:

def update(self, instance, validated_data):        # 修改商品数量        instance.nums = validated_data["nums"]        instance.save()        return instance

 2)在view中要把商品id传过去:

 因为更新单条数据,或者删除单条数据,需要用到商品id。

lookup_field = "goods_id"

trade/views.py 完整代码:

from rest_framework import viewsetsfrom rest_framework.permissions import IsAuthenticatedfrom utils.permissions import IsOwnerOrReadOnlyfrom rest_framework_jwt.authentication import JSONWebTokenAuthenticationfrom rest_framework.authentication import SessionAuthenticationfrom .serializers import ShopCartSerializerfrom .models import ShoppingCartclass ShoppingCartViewset(viewsets.ModelViewSet):    """    购物车功能    list:        获取购物车详情    create:        加入购物车    delete:        删除购物记录    """    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)    serializer_class = ShopCartSerializer    lookup_field = "goods_id"        def get_queryset(self):        return ShoppingCart.objects.filter(user=self.request.user)
ShoppingCartViewset

此时,我们访问购物车链接时,页面效果是这样的:

 

原因是因为我们序列化只返回了数量,跟一个goods querysets集合,字段缺失无法正常显示。此时我们就需要用到serializers动态方法,实现list访问时展示购物车商品信息:

1)trade/serializer.py:创建 ShopCartDetailSerializer ,购物车商品详情

class ShopCartDetailSerializer(serializers.ModelSerializer):    '''    购物车商品详情信息    '''    # 一个购物车对应一个商品    goods = GoodsSerializer(many=False, read_only=True)    class Meta:        model = ShoppingCart        fields = ("goods", "nums")

 

2)views中,注释掉:serializer_class = ShopCartSerializer ,重载:get_serializer_class() 方法

def get_serializer_class(self):        if self.action == 'list':            return ShopCartDetailSerializer        else:            return ShopCartSerializer

此时再访问购物车页面,效果就出来了:

 

这样,购物车相关功能就完成了。

购物车serializers.py完整代码:

from rest_framework import serializersfrom .models import ShoppingCartfrom goods.models import Goodsfrom goods.serializers import GoodsSerializerclass ShopCartDetailSerializer(serializers.ModelSerializer):    '''    购物车商品详情信息    '''    # 一个购物车对应一个商品    goods = GoodsSerializer(many=False, read_only=True)    class Meta:        model = ShoppingCart        fields = ("goods", "nums")class ShopCartSerializer(serializers.Serializer):    #获取当前登录的用户    user = serializers.HiddenField(        default=serializers.CurrentUserDefault()    )    nums = serializers.IntegerField(required=True, label="数量",min_value=1,                                    error_messages={                                        "min_value":"商品数量不能小于1",                                        "required": "请选择购买数量"                                    })    #goods是一个外键,可以通过这方法获取goods object中所有的值    goods = serializers.PrimaryKeyRelatedField(required=True, queryset=Goods.objects.all())    print("ser--goods:",goods)    #继承的Serializer没有save功能,必须写一个create方法    def create(self, validated_data):        # validated_data是已经处理过的数据        # 获取当前用户 → view中:self.request.user;serizlizer中:self.context["request"].user        user = self.context["request"].user        nums = validated_data["nums"]        goods = validated_data["goods"]        existed = ShoppingCart.objects.filter(user=user, goods=goods)        #如果购物车中有记录,数量+nums;如果没记录就创建,数量为nums        if existed:            existed = existed[0]            existed.nums += nums            existed.save()        else:            #添加到购物车            existed = ShoppingCart.objects.create(**validated_data)        return existed    def update(self, instance, validated_data):        # 修改商品数量        instance.nums = validated_data["nums"]        instance.save()        return instance
View Code

 

 购物车views.py完整代码:

from rest_framework import viewsetsfrom rest_framework.permissions import IsAuthenticatedfrom utils.permissions import IsOwnerOrReadOnlyfrom rest_framework_jwt.authentication import JSONWebTokenAuthenticationfrom rest_framework.authentication import SessionAuthenticationfrom .serializers import ShopCartSerializer,ShopCartDetailSerializerfrom .models import ShoppingCartclass ShoppingCartViewset(viewsets.ModelViewSet):    """    购物车功能    list:        获取购物车详情    create:        加入购物车    delete:        删除购物记录    """    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)    def get_serializer_class(self):        if self.action == 'list':            return ShopCartDetailSerializer        else:            return ShopCartSerializer    lookup_field = "goods_id"    def get_queryset(self):        return ShoppingCart.objects.filter(user=self.request.user)
ShoppingCartViewset

 

 注意:关于重载 get_object方法、get_queryset方法,两者的差别

 get_object():获取当前用户 ,在url访问方式:获取某个商品详情(get)、更新某个商品信息(update)、删除某个商品信息(delete)时,会调用

 get_queryset():url的访问方式中均会调用

如果获取所有数据(list方法),同时又有get、update、delete方法:

 1、需要获取到的是所有用户的所有数据,则使用get_object方法

 2、需要获取到的是当前用户的所有数据,则使用get_queryset方法,不需要get_object方法

def get_object(self):    return self.request.userdef get_queryset(self):    return ShoppingCart.objects.filter(user=self.request.user)

 二、订单管理接口

 客户到购物车,进行结算 → 创建订单 →保存订单信息、保存订单内每个商品的详情信息 → 查看当前用户所有订单、创建订单、删除订单,用:OrderSerializer ;查看某订单详情用:OrderDetailSerializer

views.py:

from rest_framework import viewsetsfrom rest_framework.permissions import IsAuthenticatedfrom utils.permissions import IsOwnerOrReadOnlyfrom rest_framework_jwt.authentication import JSONWebTokenAuthenticationfrom rest_framework.authentication import SessionAuthenticationfrom rest_framework import mixinsfrom .serializers import ShopCartSerializer,ShopCartDetailSerializer,OrderDetailSerializer,OrderSerializerfrom .models import ShoppingCart,OrderGoods,OrderInfoclass OrderViewset(mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin, mixins.DestroyModelMixin,                   viewsets.GenericViewSet):    """    订单管理    list:        获取个人订单    delete:        删除订单    create:        新增订单    retrieve:        获取某订单详情    """    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)    # 动态配置serializer    def get_serializer_class(self):        if self.action == "retrieve":            return OrderDetailSerializer        return OrderSerializer    # 获取订单列表    def get_queryset(self):        return OrderInfo.objects.filter(user=self.request.user)    # 在订单提交保存之前还需要多两步步骤,所以这里自定义perform_create方法    # 1.将购物车中的商品保存到OrderGoods中    # 2.清空购物车    def perform_create(self, serializer):        order = serializer.save() # 保存订单信息        # 获取购物车所有商品,存于订单内的商品详情中,然后清空购物车        shop_carts = ShoppingCart.objects.filter(user=self.request.user)        for shop_cart in shop_carts:            order_goods = OrderGoods()            order_goods.goods = shop_cart.goods            order_goods.goods_num = shop_cart.nums            order_goods.order = order            order_goods.save()            # 清空购物车            shop_cart.delete()        return order
OrderViewset

 

trade/serializers.py:

#订单中的商品class OrderGoodsSerialzier(serializers.ModelSerializer):    goods = GoodsSerializer(many=False)    class Meta:        model = OrderGoods        fields = "__all__"#订单商品信息# goods字段需要嵌套一个OrderGoodsSerializerclass OrderDetailSerializer(serializers.ModelSerializer):    goods = OrderGoodsSerialzier(many=True)    class Meta:        model = OrderInfo        fields = "__all__"class OrderSerializer(serializers.ModelSerializer):    user = serializers.HiddenField(        default=serializers.CurrentUserDefault()    )    #生成订单的时候,这些只读,不能填写添加    pay_status = serializers.CharField(read_only=True)    trade_no = serializers.CharField(read_only=True)    order_sn = serializers.CharField(read_only=True)    pay_time = serializers.DateTimeField(read_only=True)    nonce_str = serializers.CharField(read_only=True)    pay_type = serializers.CharField(read_only=True)    def generate_order_sn(self):        #生成订单号        # 当前时间+userid+随机数        from random import Random        random_ins = Random()        order_sn = "{time_str}{userid}{ranstr}".format(time_str=time.strftime("%Y%m%d%H%M%S"),                                                       userid=self.context["request"].user.id,                                                       ranstr=random_ins.randint(10, 99))        return order_sn    def validate(self, attrs):        #validate中添加order_sn,然后在view中就可以save        attrs["order_sn"] = self.generate_order_sn()        return attrs    class Meta:        model = OrderInfo        fields = "__all__"
View Code

 

urls.py配置:

# 订单的urlrouter.register(r'orders', OrderViewset, base_name="orders")

 

 

 


 

 三、pycharm远程代码调试

 参考:https://www.cnblogs.com/Eric15/articles/9593662.html

 Ubuntu系统下操作:

 1)新建虚拟环境

mkvirtualenv --python=/usr/bin/python3 mxshop

2)导出win系统下MxOnline开发环境中所依赖的包:

  导出指令:pip freeze > requirements.txt

  到当前目录下找到:requirements.txt ,将此文件复制到linux下的MxOnline虚拟环境中

  读取文件 并安装到虚拟环境中:pip install -r requirements.txt

 3)将win下mxshop数据库数据,传输到Ubuntu中的mysql中:

 win下用Navicat连接Ubuntu数据库,然后新建数据库:

 

 接着,将数据传输过去:

 


 

4)使用pycharm连接服务器ip,并将项目同步到Ubuntu中

做以下操作前,请先确定:

  1. 自己有个服务站点:比如阿里云服务端
  2. 已经在服务端创建好规则,开放好相应端口:

 

 

 

上面条件具备后,可以开始我们的操作(Ubuntu环境下):

 首先,在当前用户下新建目录:mkdir mxshop

 然后利用pycharm来同步项目:

  切记,setting中配置:ALLOWED_HOSTS = ['*']

 步骤:Tools-->>Deployment-->>Configuration  ,新增配置

 

 

 

 

 设置好后,在connection下 → 点击“Test SFTP connection”,测试连接,如果成功,则表示连上服务器,失败则需要找原因

接着,如下操作: Tools-->>Deployment-->>Configuration-->>Upload to MxShop , 会将本地当前项目同步到Ubuntu中的mxshop项目中取

5)接下来就可以进行我们的pycharm远程调试了
点击设置:

找到pycharm下的project interpreter:  将其设置为服务器虚拟环境的python ,这样相当于在服务器上运行项目了,如下操作:

  

然后就会把服务器虚拟环境中的文件全部拷贝到本地

 

点“ok”后,还会加载一些东西,耐心等待一会,完成后

 设置Host 0.0.0.0   端口  8000

 

 

pycharm上运行项目,相当于在服务器上运行项目了,访问url:

 

 

转载于:https://www.cnblogs.com/Eric15/articles/9644334.html

你可能感兴趣的文章
Mysql的安装和图形化界面的使用
查看>>
iOS 圆的放大动画效果
查看>>
ubuntu 16.04 安装cuda的方法
查看>>
silverlight 学习(-)--线性渐变画刷LinearGradientBrush
查看>>
我的秋季学期学习总结
查看>>
cocoapods Error
查看>>
第一次向nodeclub提交修改
查看>>
ionic3应用的Android打包签名发布步骤
查看>>
PetShop的系统架构设计
查看>>
获取表字段信息
查看>>
软件测试2019:第七次作业—— 用户体验测试
查看>>
加载SOS调试器扩展
查看>>
iptables 初见 第一章
查看>>
SudaMod-81.0 / crDroidAndroid-8.1(android-8.1.0_r20)红米3 2018年5月3日更新
查看>>
浅谈.net jenkins svn下自动化集成环境安装 搭建 配置
查看>>
一:数据库概述
查看>>
目录与文件的权限意义
查看>>
[C++基础]023_为什么要将基类的析构函数声明为Virtual?
查看>>
UOJ #34 多项式乘法
查看>>
xcodebuild命令行编译不通过clang: error: no such file or directory
查看>>