首页、商品数量、缓存和限速功能开发

将环境切换为本地,vue也切换为本地

轮播图

goods/serializers.py

  1. class BannerSerializer(serializers.ModelSerializer):
  2. '''
  3. 轮播图
  4. '''
  5. class Meta:
  6. model = Banner
  7. fields = "__all__"

goods/views.py

  1. class BannerViewset(mixins.ListModelMixin, viewsets.GenericViewSet):
  2. """
  3. 首页轮播图
  4. """
  5. queryset = Banner.objects.all().order_by("index")
  6. serializer_class = BannerSerializer

urls.py

  1. # 配置首页轮播图的url
  2. router.register(r'banners', BannerViewset, base_name="banners")

新品推荐功能

在设计Goods model时候有一个字段is_new

  1. is_new = models.BooleanField(default=False, verbose_name="是否新品")

实现这个接口只要在goods/filters/GoodsFilter里面添加一个过滤就可以了

  1. class Meta:
  2. model = Goods
  3. fields = ['pricemin', 'pricemax','is_hot','is_new']

首页商品分类显示功能

goods/serializers.py

  1. class BrandSerializer(serializers.ModelSerializer):
  2. '''
  3. 大类下面的宣传商标
  4. '''
  5. class Meta:
  6. model = GoodsCategoryBrand
  7. fields = "__all__"
  8. class IndexCategorySerializer(serializers.ModelSerializer):
  9. # 某个大类的商标,可以有多个商标,一对多的关系
  10. brands = BrandSerializer(many=True)
  11. # good有一个外键category,但这个外键指向的是三级类,直接反向通过外键category(三级类),取某个大类下面的商品是取不出来的
  12. goods = serializers.SerializerMethodField()
  13. # 在parent_category字段中定义的related_name="sub_cat"
  14. # 取二级商品分类
  15. sub_cat = CategorySerializer2(many=True)
  16. # 广告商品
  17. ad_goods = serializers.SerializerMethodField()
  18. def get_ad_goods(self, obj):
  19. goods_json = {}
  20. ad_goods = IndexAd.objects.filter(category_id=obj.id, )
  21. if ad_goods:
  22. # 取到这个商品Queryset[0]
  23. good_ins = ad_goods[0].goods
  24. # 在serializer里面调用serializer的话,就要添加一个参数context(上下文request),
  25. # 否则图片链接是不完整的
  26. # 嵌套serializer必须加
  27. # serializer返回的时候一定要加 “.data” ,这样才是json数据
  28. goods_json = GoodsSerializer(good_ins, many=False, context={'request': self.context['request']}).data
  29. return goods_json
  30. # 自定义获取方法
  31. def get_goods(self, obj):
  32. # 将这个商品相关父类子类等都可以进行匹配
  33. all_goods = Goods.objects.filter(Q(category_id=obj.id) | Q(category__parent_category_id=obj.id) | Q(
  34. category__parent_category__parent_category_id=obj.id))
  35. goods_serializer = GoodsSerializer(all_goods, many=True, context={'request': self.context['request']})
  36. return goods_serializer.data
  37. class Meta:
  38. model = GoodsCategory
  39. fields = "__all__"

goods/views.py

  1. class IndexCategoryViewset(mixins.ListModelMixin, viewsets.GenericViewSet):
  2. """
  3. 首页商品分类数据
  4. """
  5. # 获取is_tab=True(导航栏)里面的分类下的商品数据
  6. queryset = GoodsCategory.objects.filter(is_tab=True, name__in=["生鲜食品", "酒水饮料"])
  7. serializer_class = IndexCategorySerializer

urls.py

  1. # 首页系列商品展示url
  2. router.register(r'indexgoods', IndexCategoryViewset, base_name="indexgoods")

热搜词

goods/serializers.py

  1. class HotWordsSerializer(serializers.ModelSerializer):
  2. class Meta:
  3. model = HotSearchWords
  4. fields = "__all__"

goods/views.py

  1. class HotSearchsViewset(mixins.ListModelMixin, viewsets.GenericViewSet):
  2. """
  3. 获取热搜词列表
  4. """
  5. queryset = HotSearchWords.objects.all().order_by("-index")
  6. serializer_class = HotWordsSerializer

urls.py

  1. # 首页热搜词
  2. router.register(r'hotsearchs', HotSearchsViewset, base_name="hotsearchs")

商品点击数和收藏数

GoodsListViewSet其中继承了mixins.RetrieveModelMixin

只需要重写retrieve方法即可

  1. class GoodsListViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
  2. '''
  3. 商品列表页, 分页, 过滤, 排序
  4. '''
  5. queryset = Goods.objects.all().order_by('id')
  6. serializer_class = GoodsSerializer
  7. pagination_class = GoodsPagination
  8. filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
  9. # authentication_classes = (TokenAuthentication,)
  10. # 自定义过滤器
  11. filter_class = GoodsFilter
  12. # 搜索,默认模糊查询
  13. search_fields = ('name', 'goods_brief')
  14. # 排序
  15. ordering_fields = ('sold_num', 'shop_price')
  16. # 商品点击数 + 1
  17. def retrieve(self, request, *args, **kwargs):
  18. instance = self.get_object()
  19. instance.click_num += 1
  20. instance.save()
  21. serializer = self.get_serializer(instance)
  22. return Response(serializer.data)

UserFavViewset继承了mixins.CreateModelMixin

重写perform_create方法即可

  1. class UserFavViewset(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.CreateModelMixin, mixins.DestroyModelMixin):
  2. '''
  3. list:
  4. 获取用户的所有收藏
  5. create:
  6. 添加收藏
  7. destroy:
  8. 取消收藏
  9. '''
  10. # permission是用来做权限判断的
  11. # IsAuthenticated:必须登录用户;IsOwnerOrReadOnly:必须是当前登录的用户
  12. permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
  13. # auth使用来做用户认证的
  14. authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
  15. # 搜索的字段
  16. lookup_field = 'goods_id'
  17. def get_queryset(self):
  18. # 只能查看当前登录用户的收藏,不会获取所有用户的收藏
  19. return UserFav.objects.filter(user=self.request.user)
  20. # 动态选择serializer
  21. def get_serializer_class(self):
  22. if self.action == "list":
  23. return UserFavDetailSerializer
  24. elif self.action == "create":
  25. return UserFavSerializer
  26. return UserFavSerializer
  27. # 用户收藏的商品数量+1
  28. def perform_create(self, serializer):
  29. instance = serializer.save()
  30. # 这里instance相当于UserFav model,通过它找到goods
  31. goods = instance.goods
  32. goods.fav_num += 1
  33. goods.save()

用信号量实现收藏数变化

delete和create的时候django model都会发送一个信号量出来,用信号量的方式代码分离性更好

user_operation/signals.py

  1. from django.db.models.signals import post_delete, post_save
  2. from django.dispatch import receiver
  3. from user_operation.models import UserFav
  4. # post_save : model变化方式
  5. # sender : 变动的model
  6. @receiver(post_save, sender=UserFav)
  7. def create_userfav(sender, instance=None, created=False, **kwargs):
  8. if created:
  9. goods = instance.goods
  10. goods.fav_num += 1
  11. goods.save()
  12. @receiver(post_delete, sender=UserFav)
  13. def delete_userfav(sender, instance=None, created=False, **kwargs):
  14. goods = instance.goods
  15. goods.fav_num -= 1
  16. goods.save()

user_operation/apps.py

  1. from django.apps import AppConfig
  2. class UserOperationConfig(AppConfig):
  3. name = 'user_operation'
  4. verbose_name = "用户操作管理"
  5. def ready(self):
  6. import user_operation.signals

商品库存和销量修改

引起商品库存数量变化的行为:

  • 新增商品到购物车
  • 修改购物车数量
  • 删除购物车记录

trade/views.py

  1. class ShoppingCartViewset(viewsets.ModelViewSet):
  2. """
  3. 购物车功能
  4. list:
  5. 获取购物车详情
  6. create:
  7. 加入购物车
  8. delete:
  9. 删除购物记录
  10. """
  11. permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
  12. authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
  13. # serializer_class = ShopCartSerializer
  14. lookup_field = "goods_id"
  15. def get_queryset(self):
  16. return ShoppingCart.objects.filter(user=self.request.user)
  17. def get_serializer_class(self):
  18. if self.action == 'list':
  19. return ShopCartDetailSerializer
  20. else:
  21. return ShopCartSerializer
  22. # 库存数-n
  23. def perform_create(self, serializer):
  24. shop_cart = serializer.save()
  25. goods = shop_cart.goods
  26. goods.goods_num -= shop_cart.nums
  27. goods.save()
  28. # 库存数+n
  29. def perform_destroy(self, instance):
  30. goods = instance.goods
  31. goods.goods_num += instance.nums
  32. goods.save()
  33. instance.delete()
  34. # 更新库存,修改可能是增加页可能是减少
  35. def perform_update(self, serializer):
  36. # 首先获取修改之前的库存数量
  37. existed_record = ShoppingCart.objects.get(id=serializer.instance.id)
  38. existed_nums = existed_record.nums
  39. # 先保存之前的数据existed_nums
  40. saved_record = serializer.save()
  41. # 变化的数量
  42. nums = saved_record.nums - existed_nums
  43. goods = saved_record.goods
  44. goods.goods_num -= nums
  45. goods.save()

商品的销量只有在支付成功后才会 +n

trade/views.py

AlipayView/post方法

  1. # 查询数据库中订单记录
  2. existed_orders = OrderInfo.objects.filter(order_sn=order_sn)
  3. for existed_order in existed_orders:
  4. # 订单商品项
  5. order_goods = existed_order.goods.all()
  6. # 商品销量增加订单中数值
  7. for order_good in order_goods:
  8. goods = order_good.goods
  9. goods.sold_num += order_good.goods_num
  10. goods.save()
  11. # 更新订单状态
  12. existed_order.pay_status = trade_status
  13. existed_order.trade_no = trade_no
  14. existed_order.pay_time = datetime.now()
  15. existed_order.save()
  16. # 需要返回一个'success'给支付宝,如果不返回,支付宝会一直发送订单支付成功的消息
  17. return Response("success")

drf缓存

http://chibisov.github.io/drf-extensions/docs/#caching

  1. pip install drf-extensions

简单使用

在GoodsListViewSet中添加缓存功能

  1. from rest_framework_extensions.cache.mixins import CacheResponseMixin
  2. # CacheResponseMixin一定要放在第一个位置
  3. class GoodsListViewSet(CacheResponseMixin,mixins.ListModelMixin, mixins.RetrieveModelMixin,viewsets.GenericViewSet):

设置过期时间,settings里面

  1. # 缓存配置
  2. REST_FRAMEWORK_EXTENSIONS = {
  3. 'DEFAULT_CACHE_RESPONSE_TIMEOUT': 60*60*8 # 多少秒过期,时间自己可以随便设定
  4. }

这个缓存使用的是内存,每次重启之后就会失效

drf配置redis缓存

https://django-redis-chs.readthedocs.io/zh_CN/latest/

drf的throttle设置api的访问速率

针对爬虫

http://www.django-rest-framework.org/api-guide/throttling/

settings中配置

  1. REST_FRAMEWORK = {
  2. # 限速设置
  3. 'DEFAULT_THROTTLE_CLASSES': (
  4. 'rest_framework.throttling.AnonRateThrottle', # 未登陆用户
  5. 'rest_framework.throttling.UserRateThrottle' # 登陆用户
  6. ),
  7. 'DEFAULT_THROTTLE_RATES': {
  8. 'anon': '10/minute', # 每分钟可以请求n次
  9. 'user': '30/minute' # 每分钟可以请求n次
  10. }
  11. }

goods/views.py中使用

  1. from rest_framework.throttling import UserRateThrottle,AnonRateThrottle
  2. class GoodsListViewSet(CacheResponseMixin,mixins.ListModelMixin, mixins.RetrieveModelMixin,viewsets.GenericViewSet):
  3.   .
  4.   .
  5.   throttle_classes = (UserRateThrottle, AnonRateThrottle)

Django+Vue打造购物网站(十)的更多相关文章

  1. Django+Vue打造购物网站(九)

    支付宝沙箱环境配置 https://openhome.alipay.com/platform/appDaily.htm?tab=info 使用支付宝账号进行登陆 RSA私钥及公钥生成 https:// ...

  2. Django+Vue打造购物网站(五)

    注册和登陆 drf的认证 http://www.django-rest-framework.org/api-guide/authentication/ settings.py文件的配置 INSTALL ...

  3. Django+Vue打造购物网站(八)

    购物车.订单管理和远程调试 添加商品到购物车 trade/serializers.py from rest_framework import serializers from goods.models ...

  4. Django+Vue打造购物网站(四)

    首页商品类别数据显示 商品分类接口 大概需要两个,一个显示三个类别 一个显示类别及类别下的全部商品 现在开始写商品的接口 首先编写三个分类的serializer class CategorySeria ...

  5. Django+Vue打造购物网站(十一)

    第三方登录 微博创建应用,修改回调地址 http://open.weibo.com/authentication 安装第三方登录插件 https://github.com/python-social- ...

  6. Django+Vue打造购物网站(三)

    商品列表页 通过商品列表页面来学习drf django的view实现商品列表页 在goods目录下新建一个views_base.py文件,用来区分drf的view和Dajngo自带的view的区别 利 ...

  7. Django+Vue打造购物网站(二)

    配置后台管理 xadmin直接使用之前的在线教育的那个就可以了 users/adminx.py #!/usr/bin/env python # -*- coding: utf-8 -*- # @Tim ...

  8. Django+Vue打造购物网站(一)

    环境搭建 python == 3.6 Django == 2.0 创建工程 django-admin startproject MxShop 配置setting.py文件 # 数据库 DATABASE ...

  9. Django+Vue打造购物网站(七)

    个人中心功能开发 drf文档注释 http://www.django-rest-framework.org/topics/documenting-your-api/ 动态设置serializer和pe ...

随机推荐

  1. 我想要革命想要解脱——bootstrap常见问题及解决方式

    最近一个月,恍若隔世,天天加班,昨晚终于发版了,今天才喘一口气.有时候,即便你工作效率再怎么高,撸码再怎么快也无可避免的会加班.不信的话,可以先给你定一个交付时间,然后不断的给你加需求,就让你一个人做 ...

  2. 安卓开发:UI组件-图片控件ImageView(使用Glide)和ScrollView

    2.7ImageView 2.7.1插入本地图片 一个图片控件,可以用来显示本地和网络图片. 在首页添加按钮ImageView,指向新页面(步骤与前同,不再详写). activity_image_vi ...

  3. 自动的自动化:EvoSuite 自动生成JUnit的测试用例

    EvoSuite简介 EvoSuite是由Sheffield等大学联合开发的一种开源工具,用于自动生成测试用例集,生成的测试用例均符合Junit的标准,可直接在Junit中运行.得到了Google和Y ...

  4. 如何在MongoDB设计存储你的数据(JSON化)?

    第一步 定义要描述的数据集 当我们决定将数据存储下来的时候,我们首先要回答的一个问题就是:“我打算存储什么样的数据?这些数据之间有什么关系?实体之间有什么关系?实体的属性之间有什么关系”. 为了说明问 ...

  5. ORACLE中如何查找定位表最后DML操作的时间小结

    在Oracle数据库中,如何查找,定位一张表最后一次的DML操作的时间呢? 方式有三种,不过都有一些局限性,下面简单的解析.总结一下. 1:使用ORA_ROWSCN伪列获取表最后的DML时间 ORA_ ...

  6. 不能收缩 ID 为 %s 的数据库中 ID 为 %s 的文件,因为它正由其他进程收缩或为空。

    SQLServer数据库通常都不建议进行SHRINKFILE操作,因为SHRINKFILE不当会造成一定的性能问题. 但是当进行了某些操作(例如某个超大的日志类型表转成分区表切换了数据文件),数据库某 ...

  7. LSB和MSB

    最低有效位(the least significant bit,lsb)是指一个二进制数字中的第0位(即最低位),具有权值为2^0,可以用它来检测数的奇偶性.与之相反的称之为最高有效位.在大端序中,l ...

  8. 使用docker swarm集群心得

    本片关于使用docker swarm 集群心得,也是一些经验吧!过程描述可能简单! 根据一些公司使用经历接收一下问题并针对问题作出应对策略 1.docker swarm集群 主节点数必须是单数,也就是 ...

  9. python之并发编程

    一 背景知识 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统的其他所 ...

  10. VMware Workstation中安装linux系统(CentOS)超详细(部分转载)

    首先准备一下VMware虚拟机和linux镜像文件,链接如下: 对于32位windows机子安装的是10.0.7版本的VMware Workstation,链接: https://pan.baidu. ...