A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© gamadi 初级黑马   /  2019-6-28 09:42  /  1202 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

### 用户数据统计

- 接口设计
  - 请求方式: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表管理

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马