### 用户数据统计
- 接口设计
- 请求方式:get
- 请求路径:increments/
- 请求参数:jwt-token(判断是否有访问的权限)
- 返回结果:count,date
- 业务逻辑(***对继承视图的选择是根据功能不溢出进行判断,能用最原始的父类实现的功能就使用最原始的视图***)---使用APIView(GenericAPIView获取的是查询集对象)
- 用户登录状态的验证由jwt完成
- 查询所有用户总数
- 获取当前日期
- 返回结果
```python
from meiduo_mall.apps.users.models import User
from datetime import date
from rest_framework.views import APIView
from rest_framework.pemission import isAdminUser
# 继承自APIView,只需要用到认证功能
class IncrementTotalUserCountView(APIView):
# 设置认证,jwt自动实现认证
permission_class = [isAdminUser]
def get(self,request):
# 获取所有用户数量
users_count = User.objects.all().count()
# 获取当前时间
now_date = date.today()
# 返回结果
return Response({
'count':users_count,
'date':now_date
})
```
- jwt的token解密验证是由jwt模块完成
------
### 日增用户统计
统计当天注册过多少用户
- 接口设计
- 请求方式:get
- 请求路径:statistical/day_count/
- 请求参数:jwt-token(判断是否有访问的权限)
- 返回结果:count,date
- 业务逻辑--APIView
- 用户登录状态的验证由jwt完成
- 获取当前日期
-
- 返回结果
```python
class IncrementDayCountView(APIView):
permission_class = [isAdminUser]
def get(self,request):
now_date = date.today()
# 通过创建用户时间的与当前时间的对比,获取今天创建的用户的数量
users_count = User.objects.filter(date_joined__gte=now_date).count()
return Response({
'count':users_count,
'date':now_date
})
```
------
### 日活用户统计
**统计当天登录的用户量**
- 接口设计
- 请求方式:get
- 请求路径:statistical/login_count/
- 请求参数:jwt-token(判断是否有访问的权限)
- 返回结果:count,date
- 业务逻辑--APIView
- 用户登录状态的验证由jwt完成
- 获取当前日期
- 查询所有当天登录用户总数
- 返回结果
```python
class IncrementDayActiveCount(APIView):
# 指定权限,就是指定类,就会调用相应的方法进行验证
permission_class = [isAdminUser]
def get(self,request):
now_date = date.today()
# 用last_login(记录最近登录的时间),获取当天登录的用户数量
user_count = User.objects.filter(last_login__gte=now_date).count
return Response({
'count':user_count,
'date':now_date
})
```
------
### 下单用户统计
**当天有多少用户下单**
- 接口设计
- 请求方式:get
- 请求路径:statistical/day_orders/
- 请求参数:jwt-token(判断是否有访问的权限)
- 返回结果:count,date
- 业务逻辑--APIView
- 用户登录状态的验证由jwt完成
- 获取当前日期
- 查询所有当天下单用户总数 # **关联过滤查询订单创建时间**
- 返回结果
```python
class IncrementDayOrderView(APIView):
permission_class = [isAdminUser]
def get(self,request):
now_date = date.today()
# 订单表关联用户表,关联related_name= 'orders'用关联外键进行查询
user_count = User.objects.filter(orders__create_time__gte=now_date).count()
return Reponse({
'count':user_count,
'date':now_date
})
```
------
### 当月注册用户统计
- 接口设计
- 请求方式:get
- 请求路径:statistical/month_count/
- 请求参数:jwt-token(判断是否有访问的权限)
- 返回结果:[{count:,date:},{count:,date:}]---展示每一天的数据
- 业务逻辑--APIView
- 用户登录状态的验证由jwt完成,日期的加减处理使用timedelta()
- 获取当前日期
- 获取一个月前的日期
- for循环遍历,构建一个月内的日期,对一个月前的日期累加1
- 返回结果
```python
class IncrementMonthCountView(APIView):
permission_class = [isAdminUser]
def get(self,request):
now_date= date.today()
start_date = now_today-timedelta(days=29)
date_list = []
for i in range(30):
index_date = start_date + timedelta(days=i)
next_date = index_date + timedelta(days=1)
# 获取当天内的注册用户数量,创建日期要小于后一天
count = User.objects.filter(date_joined_gte=index_date,date_joined_lt=next_date).count()
date_list.append({
'count':count,
'date':index_date
})
return Response(date_list)
```
------
### 商品访问量的统计查询分析表
**查询数据来自于商品分类访问量(模型类)统计表**
- 接口设计
- 请求方式:get
- 请求路径:statistical/goods_day_view/
- 请求参数:jwt-token(判断是否有访问的权限)
- 返回结果:[{115:10},{130,15}] 商品分类id:访问次数
- 业务逻辑--APIView
- 用户登录状态的验证由jwt完成
- 获取当前日期
- 查询分类访问量
- 返回结果 序列化器
```python
class GoodsVisitCountView(APIView):
permission_class = [isAdminUser]
def get(self,request):
now_date = date.today()
goods_visit = GoodsVisitCount.onjects.filter(date__gte=now_date)
ser = GoodsVisitCountSerialiser(data=goods_visit,many=True)
return Reponse(ser.data)
```
[TOC]
## 用户管理
### 用户信息查询
- **查询多个数据**用ListModelMixin
- **使用分页器**用GenericAPIView
```python
from rest_framework.generics import ListAPIView
from users.models import User
from utils import PageNum
# ListAPIView继承自ListModelMixin和GenericAPIView
class UserView(ListAPIView):
serializer_class = UserSerializer
queryset = User.objects.all()
pagination_class = PageNum # 进行分页处理,指定分页器
```
```python
# 定义序列化器
from rest_framework import serializers
from users.models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User #关联模型类
fields = ('id','username','mobile','email') # 指定返回的字段
```
```python
# 分页器中原返回数据的格式不符合,需要对分页器数据返回进行改写
# 定义分页器,对分页器的返回结果进行改写
from rest_framework.pagination import PageNumberPagination
class PageNum(PageNumberPagination):
page_size = 5 # 在没有指定每页返回数量的情况下,后端默认返回的数据数量
page_size_query_param = 'page_size' # 前端指定每页数量的参数名
max_page_size = 10 # 限制每页显示最大数量
# 改写分页结果返回方法
def get_paginated_response(self,data):
return Response({
'count':self.paginator.count,
'list':data,
'page':self.page.number, # 获取当前页码
'pages':self.page.paginator.num_pages, # 获取总页数
'pagesize':self.page_size # 获取每页数据数量
})
```
------
### 实现查询用户(查询和搜索功能的统一实现)
重写get_queryset方法,根据前端传的参数,查询返回不同的数据
- 获取keyword数据:keyword = self.requast.query_params.get('keyword')
- ```python
# 重写get_queryset方法
def get_queryset(self):
keyword = self.requast.query_params.get('keyword') # 在self中存在request对象
if keyword == '' or keyword == None:
return User.objects.all()
else:
return User.objects.filter(username=keyword)
```
```python
request.data--请求体中表单非表单数据
request.FILES--获取文件
request.query_params--字典获取查询集数据
```
------
### 增加用户数据
- 序列化器的改造
```python
# 定义序列化器
from rest_framework import serializers
from users.models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','username','mobile','email','password') # 添加password字段参与反序列化
# 需要验证的字段
extra_kwargs={
'password':{
'write_only':True, # 只让password参与反序列化操作
'max_length':20,
'min_length':8
},
'username':{
'max_length':10,
'min_length':3
}
}
```
- 序列化器中重写父类create方法(因为扩展类中创建的方法时create,密码未进行加密)
```python
def create(self,validated_data):
user = User.onjects.create_user(**validated_data) # 重写后对密码进行加密
return user # user对象一定要返回
```
------
## 商品管理
### SKU表管理
**对sku表的增删改查,使用视图集完成**
- 获取sku表数据
- ```python
class SKUSerializer(serializers.ModelSerializer):
"""
SKU表数据
"""
# 返回关联spu表的名称和关联的分类表的名称
spu = serializers.StringRelatedField(read_only=True)
category = serializers.StringRelatedField(read_only=True)
# 返回模型类类的spu_id和category_id
spu_id = serializers.IntegerField()
category_id = serializers.IntegerField()
# 返回商品的规格信息 ,在商品规格详情表(SKUSpecification)中有个外键sku关了当前的SKU表
specs = SKUSpecificationSerializer(many=True)
class Meta:
model = SKU
fields = "__all__"
def create(self, validated_data):
# 1、保存sku表
specs=self.context['request'].data.get('specs') # 通过调试可以看到所得数据的类型,和获取的参数,可以实现对问题的排查
# specs = validated_data['specs']
del validated_data['specs'] # 在sku表中没有specs字段,在创建新对象是要将传来的数据中剔除
sku = SKU.objects.create(**validated_data)
# 2、保存SKU具体规格,specs是列表,进行遍历获取规格对象的信息
for spec in specs:
SKUSpecification.objects.create(sku=sku, spec_id=spec['spec_id'], option_id=spec['option_id'])
return sku
```
-
- 保存sku表数据:获取spu的id后进行关联查询规格和规格选项
- ```python
# 视图集中定义方法
# 获取商品分类表的数据
def categories(self,request): # 在路由中自定义路由方法=> as_view({'get':'categories'})
data = GoodsCategory.objects.filter(subs = None) # 获取分类表中的第三季分类,三级分类的子级为空
ser = CategoriesSerializer(data,many = true) # 调用序列化器,传入对象为多个,设置many
return Response(ser.data)
# 获取sku所关联的spu表中的数据
def goodssimple(self,request): # 要自定义路由方法匹配
data = SPU.objects.all()
ser = GoodssieSerializer(data,many=True)
return Response(ser.data)
# 获取规格和选项
def spuspecification(self,request,pk):
data = SPUSpecification.objects.filter(spu_id = pk)
ser = SPUSpecificationSerializer(data,many = True)
return Reponse(ser.data)
```
- ```python
# 商品分类的序列化器
class CategorsieSerializer(serializer.ModelSerializer):
class Meta:
model = GoodsCategory # 绑定模型类
fileds = ('id','name') # 定义返回的字段,字段放在元组当中
# spu 表的序列化器
class GoodssieSerializer(serializer.ModelSerializer):
class Meta:
model = SPU
fileds = ('id','name')
# 定义选项表的序列化器
class SpecificationOptionSerializer(serializers.ModelSerializer):
class Meta:
model = SpecificationOption
fileds = "__all__" # 或者获取前端所需要的字段('id','value')
# 商品规格序列化器,调用附表的选项数据(可以嵌套序列化器)
class SPUSpecificationSerializer(serializers.ModelSerializer):
spu = serializers.StringRelatedFiled(read_only = True) # 作为spu主表的附表,要获取的是spu的名字,不是id,就指定关联获取主表中的__str__中的属性字段
spu_id = serializer.IntegerFiled() # 获取本表中关联的spu的id数据
options = SpecificationOptionSerializer(read_only = True,many = True) # 规格表作为主表,要获取附表选项表中的数据,要调用选项表的序列化器,获取选项字段
class Meta:
model = SPUSpecification
fileds = '__all__'
```
- 更新sku表数据
- ```python
# 改写修改方法
```
-
- 删除sku表数据
- ```python
```
------
### spu表管理
|
|