Django+Vue打造购物网站(十)
首页、商品数量、缓存和限速功能开发
将环境切换为本地,vue也切换为本地
轮播图
goods/serializers.py
class BannerSerializer(serializers.ModelSerializer):
'''
轮播图
'''
class Meta:
model = Banner
fields = "__all__"
goods/views.py
class BannerViewset(mixins.ListModelMixin, viewsets.GenericViewSet):
"""
首页轮播图
"""
queryset = Banner.objects.all().order_by("index")
serializer_class = BannerSerializer
urls.py
# 配置首页轮播图的url
router.register(r'banners', BannerViewset, base_name="banners")
新品推荐功能
在设计Goods model时候有一个字段is_new
is_new = models.BooleanField(default=False, verbose_name="是否新品")
实现这个接口只要在goods/filters/GoodsFilter里面添加一个过滤就可以了
class Meta:
model = Goods
fields = ['pricemin', 'pricemax','is_hot','is_new']
首页商品分类显示功能
goods/serializers.py
class BrandSerializer(serializers.ModelSerializer):
'''
大类下面的宣传商标
'''
class Meta:
model = GoodsCategoryBrand
fields = "__all__"
class IndexCategorySerializer(serializers.ModelSerializer):
# 某个大类的商标,可以有多个商标,一对多的关系
brands = BrandSerializer(many=True)
# good有一个外键category,但这个外键指向的是三级类,直接反向通过外键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
# 自定义获取方法
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__"
goods/views.py
class IndexCategoryViewset(mixins.ListModelMixin, viewsets.GenericViewSet):
"""
首页商品分类数据
"""
# 获取is_tab=True(导航栏)里面的分类下的商品数据
queryset = GoodsCategory.objects.filter(is_tab=True, name__in=["生鲜食品", "酒水饮料"])
serializer_class = IndexCategorySerializer
urls.py
# 首页系列商品展示url
router.register(r'indexgoods', IndexCategoryViewset, base_name="indexgoods")
热搜词
goods/serializers.py
class HotWordsSerializer(serializers.ModelSerializer):
class Meta:
model = HotSearchWords
fields = "__all__"
goods/views.py
class HotSearchsViewset(mixins.ListModelMixin, viewsets.GenericViewSet):
"""
获取热搜词列表
"""
queryset = HotSearchWords.objects.all().order_by("-index")
serializer_class = HotWordsSerializer
urls.py
# 首页热搜词
router.register(r'hotsearchs', HotSearchsViewset, base_name="hotsearchs")
商品点击数和收藏数
GoodsListViewSet其中继承了mixins.RetrieveModelMixin
只需要重写retrieve
方法即可
class GoodsListViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
'''
商品列表页, 分页, 过滤, 排序
'''
queryset = Goods.objects.all().order_by('id')
serializer_class = GoodsSerializer
pagination_class = GoodsPagination
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
# authentication_classes = (TokenAuthentication,)
# 自定义过滤器
filter_class = GoodsFilter
# 搜索,默认模糊查询
search_fields = ('name', 'goods_brief')
# 排序
ordering_fields = ('sold_num', 'shop_price')
# 商品点击数 + 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)
UserFavViewset继承了mixins.CreateModelMixin
重写perform_create
方法即可
class UserFavViewset(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.CreateModelMixin, mixins.DestroyModelMixin):
'''
list:
获取用户的所有收藏
create:
添加收藏
destroy:
取消收藏
'''
# permission是用来做权限判断的
# IsAuthenticated:必须登录用户;IsOwnerOrReadOnly:必须是当前登录的用户
permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
# auth使用来做用户认证的
authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
# 搜索的字段
lookup_field = 'goods_id'
def get_queryset(self):
# 只能查看当前登录用户的收藏,不会获取所有用户的收藏
return UserFav.objects.filter(user=self.request.user)
# 动态选择serializer
def get_serializer_class(self):
if self.action == "list":
return UserFavDetailSerializer
elif self.action == "create":
return UserFavSerializer
return UserFavSerializer
# 用户收藏的商品数量+1
def perform_create(self, serializer):
instance = serializer.save()
# 这里instance相当于UserFav model,通过它找到goods
goods = instance.goods
goods.fav_num += 1
goods.save()
用信号量实现收藏数变化
delete和create的时候django model都会发送一个信号量出来,用信号量的方式代码分离性更好
user_operation/signals.py
from django.db.models.signals import post_delete, post_save
from django.dispatch import receiver
from user_operation.models import UserFav
# post_save : model变化方式
# sender : 变动的model
@receiver(post_save, sender=UserFav)
def create_userfav(sender, instance=None, created=False, **kwargs):
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()
user_operation/apps.py
from django.apps import AppConfig
class UserOperationConfig(AppConfig):
name = 'user_operation'
verbose_name = "用户操作管理"
def ready(self):
import user_operation.signals
商品库存和销量修改
引起商品库存数量变化的行为:
- 新增商品到购物车
- 修改购物车数量
- 删除购物车记录
trade/views.py
class 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)
def get_serializer_class(self):
if self.action == 'list':
return ShopCartDetailSerializer
else:
return ShopCartSerializer
# 库存数-n
def perform_create(self, serializer):
shop_cart = serializer.save()
goods = shop_cart.goods
goods.goods_num -= shop_cart.nums
goods.save()
# 库存数+n
def perform_destroy(self, instance):
goods = instance.goods
goods.goods_num += instance.nums
goods.save()
instance.delete()
# 更新库存,修改可能是增加页可能是减少
def perform_update(self, serializer):
# 首先获取修改之前的库存数量
existed_record = ShoppingCart.objects.get(id=serializer.instance.id)
existed_nums = existed_record.nums
# 先保存之前的数据existed_nums
saved_record = serializer.save()
# 变化的数量
nums = saved_record.nums - existed_nums
goods = saved_record.goods
goods.goods_num -= nums
goods.save()
商品的销量只有在支付成功后才会 +n
trade/views.py
AlipayView/post方法
# 查询数据库中订单记录
existed_orders = OrderInfo.objects.filter(order_sn=order_sn)
for existed_order in existed_orders:
# 订单商品项
order_goods = existed_order.goods.all()
# 商品销量增加订单中数值
for order_good in order_goods:
goods = order_good.goods
goods.sold_num += order_good.goods_num
goods.save()
# 更新订单状态
existed_order.pay_status = trade_status
existed_order.trade_no = trade_no
existed_order.pay_time = datetime.now()
existed_order.save()
# 需要返回一个'success'给支付宝,如果不返回,支付宝会一直发送订单支付成功的消息
return Response("success")
drf缓存
http://chibisov.github.io/drf-extensions/docs/#caching
pip install drf-extensions
简单使用
在GoodsListViewSet中添加缓存功能
from rest_framework_extensions.cache.mixins import CacheResponseMixin
# CacheResponseMixin一定要放在第一个位置
class GoodsListViewSet(CacheResponseMixin,mixins.ListModelMixin, mixins.RetrieveModelMixin,viewsets.GenericViewSet):
设置过期时间,settings里面
# 缓存配置
REST_FRAMEWORK_EXTENSIONS = {
'DEFAULT_CACHE_RESPONSE_TIMEOUT': 60*60*8 # 多少秒过期,时间自己可以随便设定
}
这个缓存使用的是内存,每次重启之后就会失效
drf配置redis缓存
https://django-redis-chs.readthedocs.io/zh_CN/latest/
drf的throttle设置api的访问速率
针对爬虫
http://www.django-rest-framework.org/api-guide/throttling/
settings中配置
REST_FRAMEWORK = {
# 限速设置
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle', # 未登陆用户
'rest_framework.throttling.UserRateThrottle' # 登陆用户
),
'DEFAULT_THROTTLE_RATES': {
'anon': '10/minute', # 每分钟可以请求n次
'user': '30/minute' # 每分钟可以请求n次
}
}
goods/views.py中使用
from rest_framework.throttling import UserRateThrottle,AnonRateThrottle
class GoodsListViewSet(CacheResponseMixin,mixins.ListModelMixin, mixins.RetrieveModelMixin,viewsets.GenericViewSet):
.
.
throttle_classes = (UserRateThrottle, AnonRateThrottle)
Django+Vue打造购物网站(十)的更多相关文章
- Django+Vue打造购物网站(九)
支付宝沙箱环境配置 https://openhome.alipay.com/platform/appDaily.htm?tab=info 使用支付宝账号进行登陆 RSA私钥及公钥生成 https:// ...
- Django+Vue打造购物网站(五)
注册和登陆 drf的认证 http://www.django-rest-framework.org/api-guide/authentication/ settings.py文件的配置 INSTALL ...
- Django+Vue打造购物网站(八)
购物车.订单管理和远程调试 添加商品到购物车 trade/serializers.py from rest_framework import serializers from goods.models ...
- Django+Vue打造购物网站(四)
首页商品类别数据显示 商品分类接口 大概需要两个,一个显示三个类别 一个显示类别及类别下的全部商品 现在开始写商品的接口 首先编写三个分类的serializer class CategorySeria ...
- Django+Vue打造购物网站(十一)
第三方登录 微博创建应用,修改回调地址 http://open.weibo.com/authentication 安装第三方登录插件 https://github.com/python-social- ...
- Django+Vue打造购物网站(三)
商品列表页 通过商品列表页面来学习drf django的view实现商品列表页 在goods目录下新建一个views_base.py文件,用来区分drf的view和Dajngo自带的view的区别 利 ...
- Django+Vue打造购物网站(二)
配置后台管理 xadmin直接使用之前的在线教育的那个就可以了 users/adminx.py #!/usr/bin/env python # -*- coding: utf-8 -*- # @Tim ...
- Django+Vue打造购物网站(一)
环境搭建 python == 3.6 Django == 2.0 创建工程 django-admin startproject MxShop 配置setting.py文件 # 数据库 DATABASE ...
- Django+Vue打造购物网站(七)
个人中心功能开发 drf文档注释 http://www.django-rest-framework.org/topics/documenting-your-api/ 动态设置serializer和pe ...
随机推荐
- dsu on tree入门
先瞎扯几句 说起来我跟这个算法好像还有很深的渊源呢qwq.当时在学业水平考试的考场上,题目都做完了不会做,于是开始xjb出题.突然我想到这么一个题 看起来好像很可做的样子,然而直到考试完我都只想出来一 ...
- Webpack4教程:第一部分,入口、输入和ES6模块
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://wanago.io/2018/07/16/webpack-4-course-par ...
- Broadcast发送广播
一.知识介绍 1.[广播分类] ①有序广播:接收者A收到广播传递给B,B传给C,有序传递.任何一个环节都可以终止广播,也可以修改广播中携带的数据. 发送的方式:sendOrderedBroadcast ...
- 南京邮电大学java第三次实验报告
实 验 报 告 ( 2017 / 2018学年 第2学期) 课程名称 JAVA语言程序设计 实验名称 Java集成开发环境的安装与使用. Java变量.表达式与控制结构 实验时间 2018 年 4 月 ...
- 2019Java查漏补缺(二)
查看了公众号:java之间的整理的集和文章,文章地址 总结和搜索了一下网络知识,总结了一下: 1.String 的hashcode()方法 2.switch总结: 3.如何实现克隆 1.String ...
- 自动给 Asp.Net Core WebApi 增加 ApiVersionNeutral
自动给 Asp.Net Core WebApi 增加 ApiVersionNeutral Intro 新增加一个 Controller 的时候,经常忘记在 Controller 上增加 ApiVers ...
- access denied for user 'root'@'localhost'(using password:YES) FOR WINDOWS
以windows为例: mysql5.5 1. 关闭正在运行的MySQL服务. 2. 打开DOS窗口,转到mysql\bin目录. 3. 输入mysqld --skip-grant-tables 回车 ...
- javaweb学习--javabean
阅读电子书<Java Web从入门到精通>密码:461c,学习JavaWeb基础知识 JavaBean类似于.net的实体类,但是规则上稍复杂一些,能实现的功能也多一些 一.介绍 1.规则 ...
- git取消跟踪已版本控制的文件
git 不再追踪文件改动 git update-index --assume-unchanged filePath git 恢复追踪文件改动 git update-index —no-assume-u ...
- 小小白搭建nextcloud云盘
我是一名linux的小小白,今天就利用自己的所学搭建属于自己的云盘——nextcloud. 本人学生狗,普通的云盘也要几十块钱,既然我们只是拿来搭建巩固自己知识并不做为生产力,我们就用VMware W ...