21- vue django restful framework 打造生鲜超市 -首页商品分类显示功能
Django2.0.2(Django-rest-framework)以及前端vue开发的前后端分离的商城网站
线上演示地址: http://vueshop.mtianyan.cn/
github源代码地址: https://github.com/mtianyan/VueDjangoFrameWorkShop
本小节:首页商品分类显示功能
首页商品分类显示功能-2
如果你还没有添加xadmin的管理类绑定。
class IndexAdAdmin(object):list_display = ["category", "goods"]xadmin.site.register(IndexAd, IndexAdAdmin)
填充brand数据。
可以看到我们在选择商品类目的时候,只能选择到一级类目。
goods/adminx.py中对于GoodsBrandAdmin重载get_context方法
def get_context(self):context = super(GoodsBrandAdmin, self).get_context()if 'form' in context:context['form'].fields['category'].queryset = GoodsCategory.objects.filter(category_type=1)return context
调用它父类的get_context方法,也就是父类本身该做的也全部做了。
if 'form' in context:这是一个固定写法
取到fields中的category。这里的名称和我们model中的名称是一样的。(model中的外键)
它的queryset我们做出限制。只取category等于1的数据。
这样可以在后台只取出字段中一部分数据。进阶开发想当有用!!!
自己手动在后台为生鲜食品大类和酒水饮料大类各添加三个品牌logo。
vue中进行联调
src/views/index/series-list.vue
created(){this.getList();}
组件在创建的时候调用了getList()
getList(){queryCategorygoods().then((response)=> {//跳转到首页页response.body面console.log(response)this.list = response.data}).catch(function (error) {console.log(error);});}
getList()调用了queryCategorygoods的接口
//获取商品类别信息
export const queryCategorygoods = params => { return axios.get(`${local_host}/indexgoods/`) }
并将该接口的数据赋值给list
对于list数据进行遍历。
前面关于goods的images等都会自动为我们加上域名,而这一次没有加上域名是为什么呢?
如果我们自己在Serializer中调用Serializer的话。
def get_ad_goods(self, obj):goods_json = {}ad_goods = IndexAd.objects.filter(category_id=obj.id, )if ad_goods:good_ins = ad_goods[0].goodsgoods_json = GoodsSerializer(good_ins, many=False).datareturn goods_json
这时候就不会自动为我们加上域名。想要让它加上域名就得加上一个参数
context={'request': self.context['request']}
image在序列化时源码中会判断是否存在上下文的request。如果存在就会加上域名。
在view中我们调用Serializer的时候,上下文会自动的给我们传进来。但是我们自己调用Serializer嵌套Serializer时不会被传进来。
商品点击数.收藏数修改
商品的GoodsListViewSet继承的 mixins.RetrieveModelMixin是获取商品的详情的。
我们可以重载其中的retrieve方法加入自己的逻辑.
原本的retrieve方法
def retrieve(self, request, *args, **kwargs):instance = self.get_object()serializer = self.get_serializer(instance)return Response(serializer.data)
添加我们逻辑的retrieve方法
def retrieve(self, request, *args, **kwargs):instance = self.get_object()instance.click_num += 1instance.save()serializer = self.get_serializer(instance)return Response(serializer.data)
收藏数
收藏的viewset中UserFavViewset
点进继承的CreateModelMixin,找到perform_create
在原基础上添加我们自己的功能。
# 收藏数+1def perform_create(self, serializer):instance = serializer.save()# 通过这个instance Userfav找到goodsgoods = instance.goodsgoods.fav_num +=1goods.save()
可以看到我们的收藏数+1了。
我们只有这一种写法吗?django的信号量也可以解决这个问题。
goods中新建一个signals.py
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiverfrom user_operation.models import UserFav# 参数一接收哪种信号,参数二是接收哪个model的信号
@receiver(post_save, sender=UserFav)
def create_user(sender, instance=None, created=False, **kwargs):# 是否新建,因为update的时候也会进行post_saveif created:goods = instance.goodsgoods.fav_num +=1goods.save()
在apps中做操作。
def ready(self):import user_operation.signals
将原来的实现perform_create注释掉
save delete都会有信号量发出的。
在用户取消收藏的时候也就是发出post_delete信号时减一
# 参数一接收哪种信号,参数二是接收哪个model的信号
@receiver(post_delete, sender=UserFav)
def del_user_fav(sender, instance=None, created=False, **kwargs):goods = instance.goodsgoods.fav_num -=1goods.save()
这时减一。
信号量可能遇到的问题xadmin创建用户密码不对.被加密两次
很简单, 你找到xadmin源码中的 UserCreationForm里面有save_models方法 你修改一下这个方法中user.set_password(self.cleaned_data["password1"])这个逻辑 把这一行删除就行了
当然删除收藏数的操作也可以在perform_destory中操作
商品库存和销量的修改
目前我们最简单粗暴的三种场景
- 新增商品到购物车
- 修改购物车数量
- 删除购物车记录
新增商品是一个create操作
直接在ShoppingCartViewset通过perform_xx实现
# 库存数-1def perform_create(self, serializer):shop_cart = serializer.save()goods = shop_cart.goodsgoods.goods_num -= shop_cart.numsgoods.save()# 库存数+1def perform_destroy(self, instance):goods = instance.goodsgoods.goods_num += instance.numsgoods.save()# 取goods在del之前取之后就被删掉了instance.delete()# 更新库存def perform_update(self, serializer):existed_record = ShoppingCart.objects.get(id=serializer.instance.id)existed_nums = existed_record.nums# 先保存之前的数据existed_numssaved_record = serializer.save()# 变化的数量nums = saved_record.nums-existed_numsgoods = saved_record.goodsgoods.goods_num -= numsgoods.save()
支付成功的销量加一
# 查询数据库中存在的订单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.goodsgoods.sold_num += order_good.goods_numgoods.save()
反向取值,通过我们在model中设置的relate_name来取值。
drf的缓存设置
加速网站的访问。
django的缓存机制。
动态网站的基本特点是它是一个动态的,每次用户请求页面它会重新计算。
有些变动比较小的数据: 如商品类别数据。可以有一定的延迟。
流量比较大时添加缓存机制。
django支持多种backend机制。redis memorycache
setting中设置一下就好了。
drf的缓存
https://github.com/chibisov/drf-extensions
这是drf的一个扩展,不止增强了缓存还有其他的。
pip install drf-extensions
缓存viewset中的retrieve和list 方法是很常见的。这就是为什么CacheResponseMixin存在。
获取数据的才会用到cache
from rest_framework_extensions.cache.mixins import CacheResponseMixin
把这个CacheResponseMixin,放在list之前。尽量放在第一个继承的类
class GoodsListViewSet(CacheResponseMixin,mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
设置过期时间
REST_FRAMEWORK_EXTENSIONS = {'DEFAULT_CACHE_RESPONSE_TIMEOUT': 5
}
根据自己需求加缓存。目前这个缓存使用的是内存。每次系统重启会丢失
drf的redis缓存设置
如何将redis作为backend
redis提供了一个client,我们可以进行观察key值比较透明。
redis中是保存html,还是保存json格式数据都是需要我们考虑的。
drf是兼容这两种模式的。
即使是商品列表页,加上过滤器参数之后,不同的人加上了不同的过滤器,肯定是不能用gods_list这个什么参数都不加的访问结果的。
所以缓存还应该与请求的参数挂钩,参数是什么,对应的返回结果是什么
django-redis的第三方库
http://django-redis-chs.readthedocs.io/zh_CN/latest/
pip install django-redis
向setting中加入
CACHES = {"default": {"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://127.0.0.1:6379","OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient",}}
}
前提是请自行安装好redis
配置密码
直接密码@127
后面的1指数据库。连接池解释器等。
可以看到redis缓存成功。只有goods页面拥有缓存
key对于url参数进行了生成。json和html内容生成不同的key。
同样规则的人取出同样的数据,不同规则取不同数据。
drf的throttle设置api的访问速率
防止爬虫。无节制的爬取数据。服务器的压力。
对于某些关键数据进行限速访问。人为点击速度没有那么大。
api数据工整。
drf的自带功能。
http://www.django-rest-framework.org/api-guide/throttling/
throttle配置到setting中
'DEFAULT_THROTTLE_CLASSES': ('rest_framework.throttling.AnonRateThrottle','rest_framework.throttling.UserRateThrottle'),'DEFAULT_THROTTLE_RATES': {'anon': '100/day','user': '1000/day'}
限速规则与限速的类。未登录情况下限速,通过ip地址。登录情况下通过session或token来判断。
模拟登录。对于用户登录之后也做限制。
The rate descriptions used in DEFAULT_THROTTLE_RATES may include second, minute, hour or day as the throttle period.
设置到我们的接口
from rest_framework.throttling import UserRateThrottle,AnonRateThrottlethrottle_classes = (UserRateThrottle, AnonRateThrottle)
parse_rate进行解析我们的规则
allow_request中使用django的cache进行缓存。将每个ip的访问次数设置到缓存中
get_ident会通过request.meta.get('remote_addr')取出ip
已登录用户的限制是通过
request.user.pk
21- vue django restful framework 打造生鲜超市 -首页商品分类显示功能相关推荐
- 10- vue django restful framework 打造生鲜超市 -用户登录和手机注册(中)
Vue+Django REST framework实战 搭建一个前后端分离的生鲜超市网站 Django rtf 完成 手机注册和用户登录(中) Json Web Token的原理 因为我们的drf 的 ...
- 7- vue django restful framework 打造生鲜超市 -商品类别数据展示(上)
Vue+Django REST framework实战 搭建一个前后端分离的生鲜超市网站 Django rtf 完成 商品列表页 并没有将列表页的数据json 与前端的页面展示结合起来 讲解如果将dr ...
- 5- vue django restful framework 打造生鲜超市 -完成商品列表页(上)
使用Python3.6与Django2.0.2(Django-rest-framework)以及前端vue开发的前后端分离的商城网站 项目支持支付宝支付(暂不支持微信支付),支持手机短信验证码注册, ...
- 4- vue django restful framework 打造生鲜超市 -restful api 与前端源码介绍
使用Python3.6与Django2.0.2(Django-rest-framework)以及前端vue开发的前后端分离的商城网站 项目支持支付宝支付(暂不支持微信支付),支持手机短信验证码注册, ...
- Vue+Django REST framework打造生鲜电商项目
1-1 课程导学 2-1 Pycharm的安装和简单使用 2-2 MySQL和Navicat的安装和使用 2-3 Windows和Linux下安装Python2和Python3 2-4 虚拟环境的安装 ...
- python全栈生鲜电商_Vue+Django REST framework 打造生鲜电商项目(学习笔记一)
1.环境搭建 所需软件的版本: 1)pycharm(使用professional版本) 2)mysql.navicat 安装好的mysql后需要给root权限,不然只能通过localhost访问本地的 ...
- Django REST framework+Vue 打造生鲜超市(四)
目录 生鲜超市(一) 生鲜超市(二) 生鲜超市(三) 生鲜超市(四) 生鲜超市(五) 生鲜超市(六) 生鲜超市(七) 生鲜超市(八) 生鲜超市(九) 生鲜超市(十) ...
- python全栈生鲜电商_Python前后端分离开发Vue+Django REST framework全栈打造生鲜电商项目...
vue项目采用当前流行的前后端分离式开发技术,涉及RESTFul API基础知识和Vue项目结构分析,解决了技术开发单一的痛点,拥有超前的技术融合技能,让你在开发的领域比别人技高一筹! 1.项目初始化 ...
- 在django restful framework中设置django model的property
众所周知,在django的model中,可以某些字段设置@property和setter deleter getter,这样就可以在存入数据的时候进行一些操作,具体原理请参见廖雪峰大神的博客https ...
最新文章
- android studio没有org.apache.http.client.HttpClient;等包问题 解决方案
- IE遭破坏后的自我修复方法
- Python_summary
- python集合类型中的元素是有序的_Python基础-2-变量和数据类型(2)-列表、元组、字典、集合...
- Linux学习1——文件权限
- [如何做研究][如何写论文]
- Magento教程 24:如何发送电子报! (Newsletter)
- SQL基础:数据表的创建
- c语言按键实现跳转程序,C语言中的跳转语句
- Executor框架(转载)
- 申请美国大学计算机专业,申请美国大学计算机CS专业的4个要点
- php生成五星红旗,php基于GD库画五星红旗的方法_PHP
- 百度的疯狂 UC的隐忍
- Podium Vue客户端组件库
- 1671. Anansi's Cobweb(并查集)
- 神奇的递归!一文读懂函数递归(python实现)
- 面试官:SPA(单页应用)首屏加载速度慢怎么解决?
- .net WebApi中使用swagger
- Xmouse 修改鼠标侧面按钮
- 移动云Mas最稳定的发送方式