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数据。

mark

可以看到我们在选择商品类目的时候,只能选择到一级类目。

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()

mark

可以看到我们的收藏数+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中操作

商品库存和销量的修改

目前我们最简单粗暴的三种场景

  1. 新增商品到购物车
  2. 修改购物车数量
  3. 删除购物车记录

新增商品是一个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指数据库。连接池解释器等。

mark

可以看到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)

mark

parse_rate进行解析我们的规则

allow_request中使用django的cache进行缓存。将每个ip的访问次数设置到缓存中

get_ident会通过request.meta.get('remote_addr')取出ip

已登录用户的限制是通过

request.user.pk

21- vue django restful framework 打造生鲜超市 -首页商品分类显示功能相关推荐

  1. 10- vue django restful framework 打造生鲜超市 -用户登录和手机注册(中)

    Vue+Django REST framework实战 搭建一个前后端分离的生鲜超市网站 Django rtf 完成 手机注册和用户登录(中) Json Web Token的原理 因为我们的drf 的 ...

  2. 7- vue django restful framework 打造生鲜超市 -商品类别数据展示(上)

    Vue+Django REST framework实战 搭建一个前后端分离的生鲜超市网站 Django rtf 完成 商品列表页 并没有将列表页的数据json 与前端的页面展示结合起来 讲解如果将dr ...

  3. 5- vue django restful framework 打造生鲜超市 -完成商品列表页(上)

    使用Python3.6与Django2.0.2(Django-rest-framework)以及前端vue开发的前后端分离的商城网站 项目支持支付宝支付(暂不支持微信支付),支持手机短信验证码注册, ...

  4. 4- vue django restful framework 打造生鲜超市 -restful api 与前端源码介绍

    使用Python3.6与Django2.0.2(Django-rest-framework)以及前端vue开发的前后端分离的商城网站 项目支持支付宝支付(暂不支持微信支付),支持手机短信验证码注册, ...

  5. Vue+Django REST framework打造生鲜电商项目

    1-1 课程导学 2-1 Pycharm的安装和简单使用 2-2 MySQL和Navicat的安装和使用 2-3 Windows和Linux下安装Python2和Python3 2-4 虚拟环境的安装 ...

  6. python全栈生鲜电商_Vue+Django REST framework 打造生鲜电商项目(学习笔记一)

    1.环境搭建 所需软件的版本: 1)pycharm(使用professional版本) 2)mysql.navicat 安装好的mysql后需要给root权限,不然只能通过localhost访问本地的 ...

  7. Django REST framework+Vue 打造生鲜超市(四)

    目录 生鲜超市(一)    生鲜超市(二)    生鲜超市(三) 生鲜超市(四)    生鲜超市(五)    生鲜超市(六) 生鲜超市(七)    生鲜超市(八)    生鲜超市(九) 生鲜超市(十) ...

  8. python全栈生鲜电商_Python前后端分离开发Vue+Django REST framework全栈打造生鲜电商项目...

    vue项目采用当前流行的前后端分离式开发技术,涉及RESTFul API基础知识和Vue项目结构分析,解决了技术开发单一的痛点,拥有超前的技术融合技能,让你在开发的领域比别人技高一筹! 1.项目初始化 ...

  9. 在django restful framework中设置django model的property

    众所周知,在django的model中,可以某些字段设置@property和setter deleter getter,这样就可以在存入数据的时候进行一些操作,具体原理请参见廖雪峰大神的博客https ...

最新文章

  1. android studio没有org.apache.http.client.HttpClient;等包问题 解决方案
  2. IE遭破坏后的自我修复方法
  3. Python_summary
  4. python集合类型中的元素是有序的_Python基础-2-变量和数据类型(2)-列表、元组、字典、集合...
  5. Linux学习1——文件权限
  6. [如何做研究][如何写论文]
  7. Magento教程 24:如何发送电子报! (Newsletter)
  8. SQL基础:数据表的创建
  9. c语言按键实现跳转程序,C语言中的跳转语句
  10. Executor框架(转载)
  11. 申请美国大学计算机专业,申请美国大学计算机CS专业的4个要点
  12. php生成五星红旗,php基于GD库画五星红旗的方法_PHP
  13. 百度的疯狂 UC的隐忍
  14. Podium Vue客户端组件库
  15. 1671. Anansi's Cobweb(并查集)
  16. 神奇的递归!一文读懂函数递归(python实现)
  17. 面试官:SPA(单页应用)首屏加载速度慢怎么解决?
  18. .net WebApi中使用swagger
  19. Xmouse 修改鼠标侧面按钮
  20. 移动云Mas最稳定的发送方式

热门文章

  1. C# 邮件类 Mailmessage
  2. 网站建设过程中的:重要页面、关键页面、过程页面、结果页面
  3. asp.net MVC留言本示例
  4. (转)Oracle程序包(存储过程)返回记录集
  5. 奇安信代码安全实验室帮助微软修复多个高危漏洞,获官方致谢
  6. 思科警告:“关键更新”钓鱼攻击窃取用户 Webex 凭证
  7. 苹果全面开放漏洞奖励计划:最高100万美元等你拿
  8. 各个 Maven仓库 镜像(包括国内)
  9. Python学习之使用Python发送邮件
  10. linux 命令详解 二十四