(from:https://www.cnblogs.com/derek1184405959/p/8877643.html  有修改)

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

首先把pycharm环境改成本地的,vue中local_host也改成本地

1、轮播图接口实现

(1)goods/serializer

class BannerSerializer(serializers.ModelSerializer):
'''
轮播图
'''
class Meta:
model = Banner
fields = "__all__"

(2)goods/views.py

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

(3)url

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

2、新品接口功能开发

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

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

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

class Meta:
model = Goods
fields = ['pricemin', 'pricemax','is_hot','is_new']

3、首页商品分类显示功能

首先是大类,然后里面有

  • 商品商标(多个)
  • 大类下的二级类
  • 广告商品
  • 所有商品

(1)goods/serializers.py

class BrandSerializer(serializers.ModelSerializer):
'''
大类下面的宣传商标
'''
class Meta:
model = GoodsCategoryBrand
fields = "__all__" class IndexCategorySerializer(serializers.ModelSerializer):
#某个大类的商标,可以有多个商标,一对多的关系
brands = BrandSerializer(many=True)
   # 这里容易犯的错是用goods = GoodsSerialize(),但是这是错的。
# good虽然有一个外键category,但这个外键指向的是三级类,(因为商品一般都是放在第三类之下)。但是我们的GoodsCategory是一级类。
# 直接反向通过外键category(三级类),取某个大类下面的商品是取不出来的 
# 所以要自定义获取方法,不管这个商品是放在一类、二类还是三类下,都可以进行获取
goods = serializers.SerializerMethodField()
# 在parent_category字段中定义的related_name="sub_cat"
# 取二级商品分类
sub_cat = CategorySerializer2(many=True)
# 广告商品
ad_goods = serializers.SerializerMethodField() def get_ad_goods(self, obj):
goods_json = {}
ad_goods = IndexAd.objects.filter(category_id=obj.id)
if ad_goods:
# 取到这个商品Queryset[0]
good_ins = ad_goods[0].goods
# (重点!!!)在serializer里面调用serializer的话,就要添加一个参数context(上下文request),嵌套serializer必须加,否则路径不会补全
# serializer返回的时候一定要加 “.data” ,这样才是json数据
goods_json = GoodsSerializer(good_ins, many=False, context={'request': self.context['request']}).data
return goods_json # 自定义获取方法
# 格式"get_XXX(self, obj)"
# obj就是model对象
def get_goods(self, obj):
# 将这个商品相关父类子类等都可以进行匹配
all_goods = Goods.objects.filter(Q(category_id=obj.id) | Q(category__parent_category_id=obj.id) | Q(
category__parent_category__parent_category_id=obj.id))
goods_serializer = GoodsSerializer(all_goods, many=True, context={'request': self.context['request']})
return goods_serializer.data class Meta:
model = GoodsCategory
fields = "__all__"

(2)goods/views.py

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

(3)url

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

4、商品点击数和收藏数

(1)获取商品的点击数

GoodsListViewSet其中继承了mixins.RetrieveModelMixin(获取商品详情)

源码

class RetrieveModelMixin(object):
"""
Retrieve a model instance.
"""
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response(serializer.data)

我们只要重写他的retrieve方法就可以了

goods/views

#商品点击数 + 1
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
instance.click_num += 1
instance.save()
serializer = self.get_serializer(instance)
return Response(serializer.data)

(3)用信号量实现收藏数的+1和-1

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

(1)user_operation/signal.py

# users_operation/signals.py

from django.db.models.signals import post_save,post_delete
from django.dispatch import receiver
from user_operation.models import UserFav # post_save:接收信号的方式
#sender: 接收信号的model
@receiver(post_save, sender=UserFav)
def create_UserFav(sender, instance=None, created=False, **kwargs):
# 是否新建,因为update(修改)的时候也会进行post_save
if created:
goods = instance.goods
goods.fav_num += 1
goods.save() @receiver(post_delete, sender=UserFav)
def delete_UserFav(sender, instance=None, created=False, **kwargs):
goods = instance.goods
goods.fav_num -= 1
goods.save()

(2)user_operation/apps.py

from django.apps import AppConfig

class UserOperationConfig(AppConfig):
name = 'user_operation'
verbose_name = "操作管理" def ready(self):
import user_operation.signals

5、商品库存和销量修改

库存数量

商品库存数量的行为:

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

trade/views.py

# 添加到购物车后,修改库存数
def perform_create(self, serializer):
shop_cart = serializer.save()
goods = shop_cart.goods
goods.goods_num -= shop_cart.nums
goods.save() # 删除购物车,修改库存数
def perform_destroy(self, instance):
goods = instance.goods
goods.goods_num += instance.nums
goods.save()
instance.delete() # 修改购物车记录
def perform_update(self, serializer):
# 获取修改前购物车的记录
# 获取modelform对应的实例
exited_record = ShoppingCart.objects.filter(id=serializer.instance.id)
# 购物车商品数量
exited_nums = exited_record.nums
# 修改后购物车记录
saved_record = serializer.save()
# 修改前后购物车商品数量变化
nums = saved_record.nums - exited_nums
# 获取库存商品
goods = saved_record.goods
# 修改库存商品数量
goods.goods_num -= nums
goods.save()

商品销量

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

这一部分功能是写在AlipayView上的,因为我没有配置阿里支付宝付费服务,所以没有写

trade/views.py

for order_good in order_goods:
goods = order_good.goods
goods.sold_num += order_good.goods_num
goods.save()

6、drf的缓存设置

为了加速网站的访问速度,将一些数据放到缓存当中,取数据的时候首先去缓存中去,然后再去数据库中取

我们用drf的一个扩展来实现缓存,github上面的使用说明:http://chibisov.github.io/drf-extensions/docs/#caching

(1)安装

pip install drf-extensions

(2)使用方法

导入

from rest_framework_extensions.cache.mixins import CacheResponseMixin

在GoodsListViewSet中添加缓存功能

#CacheResponseMixin一定要放在第一个位置
class GoodsListViewSet(CacheResponseMixin,mixins.ListModelMixin, mixins.RetrieveModelMixin,viewsets.GenericViewSet):

设置过期时间,settings里面

#缓存配置
REST_FRAMEWORK_EXTENSIONS = {
'DEFAULT_CACHE_RESPONSE_TIMEOUT': 5 #5s过期,时间自己可以随便设定
}

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

7、drf配置redis缓存

使用django-redis第三方库:http://django-redis-chs.readthedocs.io/zh_CN/latest/#id8    (文档说明)

(1)安装

pip install django-redis

(2)在setting.py里添加

# redis缓存
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}

8、drf的throttle设置api的访问速率

为了防止爬虫对服务器造成的重大压力,对数据进行访问速率限制就显得非常的重要了

官网使用说明:http://www.django-rest-framework.org/api-guide/throttling/

(1)settings中配置

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
#限速设置
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle', #未登陆用户,根据ip判断
'rest_framework.throttling.UserRateThrottle' #登陆用户,根据token判断
),
'DEFAULT_THROTTLE_RATES': {
'anon': '3/minute', #每分钟可以请求三次
'user': '5/minute' #每分钟可以请求五次
}

(2)goods/views.py中使用

Django REST framework+Vue 打造生鲜电商项目(笔记十)的更多相关文章

  1. Django REST framework+Vue 打造生鲜电商项目(笔记二)

    (转自https://www.cnblogs.com/derek1184405959/p/8768059.html)(有修改) 接下来开始引入django resfulframework,体现它的强大 ...

  2. Django REST framework+Vue 打造生鲜电商项目(笔记四)

    (PS:部分代码和图片来自博客:http://www.cnblogs.com/derek1184405959/p/8813641.html.有增删) 一.用户登录和手机注册 1.drf的token功能 ...

  3. Django REST framework+Vue 打造生鲜电商项目(笔记九)

    (from:http://www.cnblogs.com/derek1184405959/p/8859309.html) 十二.支付宝沙箱环境配置 12.1.创建应用 进入蚂蚁金服开放平台(https ...

  4. Django REST framework+Vue 打造生鲜电商项目(笔记三)

    (PS:转载自http://www.cnblogs.com/derek1184405959/p/8810591.html  有修改) 一.drf的过滤 (1)添加到app里面 INSTALLED_AP ...

  5. Django REST framework+Vue 打造生鲜电商项目(笔记十一)

    (form: http://www.cnblogs.com/derek1184405959/p/8886796.html 有修改) 十四.social_django 集成第三方登录 1.申请应用 进入 ...

  6. Django REST framework+Vue 打造生鲜电商项目(笔记八)

    (form:http://www.cnblogs.com/derek1184405959/p/8862569.html) 十一.pycharm 远程代码调试 第三方登录和支付,都需要有服务器才行(回调 ...

  7. Django REST framework+Vue 打造生鲜电商项目(笔记七)

    十.购物车.订单管理和支付功能 1.添加商品到购物车 (1)trade/serializer.py 这里的serializer不继承ModelSerializer,是因为自己写的Serializer更 ...

  8. Django REST framework+Vue 打造生鲜电商项目(笔记一)

    首先,这系列随笔是我个人在学习Bobby老师的Django实战项目中,记录的觉得对自己来说比较重要的知识点,不是完完整整的项目步骤过程....如果有小伙伴想找完整的教程,可以看看这个(https:// ...

  9. Django REST framework+Vue 打造生鲜电商项目(笔记六)

    (部分代码来自https://www.cnblogs.com/derek1184405959/p/8836205.html) 九.个人中心功能开发 1.drf的api文档自动生成 (1) url #d ...

随机推荐

  1. phaser三个学生做题目

    3个学生一起参加考试,一共有三道题,要求所有学生到齐才能开始考试,全部同学都做完第一题,学生才能继续做第二题,全部学生做完了第二题,才能做第三题,所有学生都做完的第三题,考试才结束 public cl ...

  2. 获取可视区域高度赋值给div(解决document.body.clientHeight的返回值为0的问题)

    设置html,body{height:100%} 在使用html5文档类型的时候, 设置了html body的高度100%之后,两个浏览器就都能获取document.body.clientHeight ...

  3. [转帖]iis最大并发连接数、队列长度、最大并发线程数、最大工作进程数

    iis最大并发连接数.队列长度.最大并发线程数.最大工作进程数 2018-10-17 12:49:03 牛兜兜 阅读数 2952   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议 ...

  4. 用php做管理后台

    最近因处理家庭之事,技术上没有提高,这段时间也陆续的恢复了正常的开发,由于要做一个管理后台,所以在选择语言和架构上搜了不少资料, php 和java 的选择上,后来选择用php作为管理后台开发的语言. ...

  5. 使用AOP进行权限验证

    首先我们定义一个切入点(匹配com.ed.controller.Seller开头的controller的所有public方法) @Pointcut("execution(public * c ...

  6. PAT(B) 1059 C语言竞赛(C)

    题目链接:1059 C语言竞赛 (20 point(s)) 题目描述 C 语言竞赛是浙江大学计算机学院主持的一个欢乐的竞赛.既然竞赛主旨是为了好玩,颁奖规则也就制定得很滑稽: 冠军将赢得一份" ...

  7. Android studio 3.1.3真机调试报错,no target device found

    Android studio 3.1.2 的 Android monitor 改为 Android profiler,直接点这个就可以真机调试,在手机安装相应app 如果不行,报错,"no ...

  8. Ubuntu Server Swap 分区设置

    方案一:仅在内存耗尽的情况下才使用 swap 分区 # 首先进入 sudo 模式 sysctl vm.swappiness=0 # 临时生效 echo "vm.swappiness = 0& ...

  9. 优先队列问题 get it !!

    首先 队列的基本用法 头文件 #include<queue> priority_queue < int/string/struct> q//  q为队列的名字 基本操作 q.p ...

  10. ubuntu环境下pycharm编译程序import包出错:ImportError: dynamic module does not define init function (init_caffe)

    出错原因是因为pycharm中的python版本不对,比如程序为2.7版本,但是pycharm编解释器为python3,导致出错,去setting改一下版本就行:pycharm>file> ...