课程分类接口、课程群查接口、分页组件、搜索组件、过滤组件、分类过滤
目录
复习
"""
1)谈一谈redis数据库持久化机制
主动:save
自动:900:1 300:10 60:10000
被动:异常退出自动调用save
文件:dump.rbd
2)什么样的接口数据一般会做缓存处理,接口缓存的原理是什么
缓存接口一般:大量访问、数据较固定、时间的时效性要求不高
缓存原理:优先找缓存数据,有走缓存,没有走数据库更新缓存
缓存技术:django cache (redis)
3)介绍一下celery异步任务框架,组成部分,工作原理
框架:独立运行的服务
组成:broker(中间件) > worker(执行者) > backend(结果仓库)
应用:Celery(broker, backend, include) # include就是任务文件
封装:
模块:在模块内有Celery()应用对象
包:包内必须有celery.py文件,在文件内有Celery()应用对象 ***
命令:
>: cd 包所在的文件夹
>: celery worker -A 包名 -l info -P eventlet
工作:
脚本或正常服务,为celery框架添加任务到broker
celery会自动从broker中拿任务执行
将执行的任务结果放在backend
脚本或正常服务,可以再在backend中获取任务执行结果
4)celery框架可以帮我们解决哪些问题,可以举例阐述一下
异步执行:耗时任务 - 服务器同步客户端生成的视频
延迟执行:延迟任务 - 延迟发送邮件
定时执行:周期任务 - 定时更新缓存
5)轮播图接口缓存更新
将接口的缓存清除(cache.set('banner_list', '', -1) | cache.delete('banner_list'))
"""
课程分类群查接口
serializers.py
from rest_framework import serializers
from . import models
class CourseCategorySerializer(serializers.ModelSerializer):
class Meta:
model = models.CourseCategory
fields = ('name', )
views.py
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
from . import models, serializers
# 课程分类群查
class CourseCategoryViewSet(GenericViewSet, ListModelMixin):
queryset = models.CourseCategory.objects.filter(is_delete=False, is_show=True).all()
serializer_class = serializers.CourseCategorySerializer
urls.py
router.register('categories', views.CourseCategoryViewSet, 'categories')
课程群查接口
serializers.py
# 子序列化
class TeacherSerializer(serializers.ModelSerializer):
class Meta:
model = models.Teacher
fields = ('name', 'role_name', 'title', 'signature', 'image', 'brief')
class CourseSerializer(serializers.ModelSerializer):
# teacher = TeacherSerializer(many=False)
class Meta:
model = models.Course
fields = ('id', 'name', 'price')
# fields = (
# 'id',
# 'name',
# 'course_img',
# 'brief',
# 'attachment_path',
# 'pub_sections',
# 'price',
# 'students',
# 'period',
# 'sections',
# 'course_type_name',
# 'level_name',
# 'status_name',
# 'teacher',
# 'section_list',
# )
views.py
class CourseViewSet(GenericViewSet, ListModelMixin):
queryset = models.Course.objects.filter(is_delete=False, is_show=True).all()
serializer_class = serializers.CourseSerializer
urls.py
router.register('free', views.CourseViewSet, 'free')
分页组件
""" 分页组件的使用
1)重写分页类 - 自定义同名类继承drf的分页类
2)完成必要的配置
3)将重写的分页类配置给群查需求的视图类
"""
pagination.py 配置
from rest_framework.pagination import PageNumberPagination as DrfPageNumberPagination
# 基础分页器
class PageNumberPagination(DrfPageNumberPagination):
# 默认一页显示的条数
page_size = 2
# url中携带页码的key
page_query_param = 'page'
# url中用户携带自定义一页条数的key
page_size_query_param = 'page_size'
# 用户最大可自定义一页的条数
max_page_size = 3
# 偏移分页器
from rest_framework.pagination import LimitOffsetPagination as DrfLimitOffsetPagination
class LimitOffsetPagination(DrfLimitOffsetPagination):
# 默认一页显示的条数
default_limit = 2
# url中用户携带自定义一页条数的key
limit_query_param = 'limit'
# url中用户携带自定义偏移条数的key
offset_query_param = 'offset'
# 用户最大可自定义一页的条数
max_limit = 2
from rest_framework.pagination import CursorPagination as DrfCursorPagination
class CursorPagination(DrfCursorPagination):
# 默认一页显示的条数
page_size = 2
# url中携带页码的key(编码后的结果)
cursor_query_param = 'cursor'
# url中用户携带自定义一页条数的key
page_size_query_param = 'page_size'
# 用户最大可自定义一页的条数
max_page_size = 3
# 按照什么排序,默认升序,加-号就是降序
ordering = 'price'
# 游标分页器的特殊点:
# 1)如果视图类没有配 排序过滤组件filter_backends = [OrderingFilter],采用 ordering 设置的作为默认排序规则
# 2)如果视图类配了 排序过滤组件filter_backends = [OrderingFilter],url请求必须带上ordering排序规则,因为默认排序规则失效
# 注:因为游标分页是基于排序后结果上的分页
views.py 分页器使用
# 分页组件:基础分页(采用)、偏移分页、游标分页(了解)
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
from . import pagination
# 过滤组件:搜索功能、排序功能
from rest_framework.filters import SearchFilter, OrderingFilter
from .filters import CountFilter
class CourseViewSet(GenericViewSet, ListModelMixin):
queryset = models.Course.objects.filter(is_delete=False, is_show=True).all()
serializer_class = serializers.CourseSerializer
# 分页组件
#方法一:直接使用drf分页类,在视图类中完成分页类的必要配置
pagination_class = PageNumberPagination
PageNumberPagination.page_size = 1
# 方法二:自定义分页类继承drf分页类,在自定义分页类中完成配置,视图类中使用自定义分页类
# 基础分页器
pagination_class = pagination.PageNumberPagination
# 偏移分页器,没有固定页码,自定义从偏移量开始往后查询自定义条数
pagination_class = pagination.LimitOffsetPagination
# 游标分页器
pagination_class = pagination.CursorPagination
搜索组件
"""
搜索组件
1)在视图文件views.py中导入drf的搜索组件
from rest_framework.filters import SearchFilter
2)将搜索组件配置给群查接口视图类的filter_backends
filter_backends = [SearchFilter]
3)配置视图类关联的Model表参与搜索的字段
search_fields = ['name', 'id']
4)前台访问该群查接口,采用拼接参数方式用search关键字将搜索目标提供给后台
http://127.0.0.1:8000/course/free/?search=2 # id或name中包含2的所有结果
http://127.0.0.1:8000/course/free/?search=python # id或name中包含2的所有结果
"""
views.py 搜索组件使用
可以配合分页器使用,分页
# 分页组件:基础分页(采用)、偏移分页、游标分页(了解)
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
from . import pagination
# 过滤组件:搜索功能、排序功能
from rest_framework.filters import SearchFilter, OrderingFilter
from .filters import CountFilter
class CourseViewSet(GenericViewSet, ListModelMixin):
queryset = models.Course.objects.filter(is_delete=False, is_show=True).all()
serializer_class = serializers.CourseSerializer
# 分页组件
# 方法一:直接使用drf分页类,在视图类中完成分页类的必要配置
# pagination_class = PageNumberPagination
# PageNumberPagination.page_size = 1
# 方法二:自定义分页类继承drf分页类,在自定义分页类中完成配置,视图类中使用自定义分页类
# 基础分页器
# pagination_class = pagination.PageNumberPagination
# 偏移分页器,没有固定页码,自定义从偏移量开始往后查询自定义条数
# pagination_class = pagination.LimitOffsetPagination
# 游标分页器
# pagination_class = pagination.CursorPagination
# 过滤组件:实际开发,有多个过滤条件时,要把优先级高的放在前面
filter_backends = [SearchFilter, OrderingFilter, CountFilter] # 多个组件
# 参与搜索的字段
search_fields = ['name', 'id']
# 允许排序的字段
ordering_fields = ['id', 'price']
排序组件
"""
排序组件
1)在视图文件views.py中导入drf的搜索组件
from rest_framework.filters import OrderingFilter
2)将搜索组件配置给群查接口视图类的filter_backends
filter_backends = [OrderingFilter]
3)配置视图类关联的Model表允许排序的字段
ordering_fields = ['id', 'price']
4)前台访问该群查接口,采用拼接参数方式用search关键字将搜索目标提供给后台
http://127.0.0.1:8000/course/free/?ordering=price,-id # 按price升序,如果price相同,再按id降序
"""
views.py 排序使用
# 过滤组件:搜索功能、排序功能
from rest_framework.filters import SearchFilter, OrderingFilter
from .filters import CountFilter
class CourseViewSet(GenericViewSet, ListModelMixin):
queryset = models.Course.objects.filter(is_delete=False, is_show=True).all()
serializer_class = serializers.CourseSerializer
# 分页组件
# 方法一:直接使用drf分页类,在视图类中完成分页类的必要配置
# pagination_class = PageNumberPagination
# PageNumberPagination.page_size = 1
# 方法二:自定义分页类继承drf分页类,在自定义分页类中完成配置,视图类中使用自定义分页类
# 基础分页器
# pagination_class = pagination.PageNumberPagination
# 偏移分页器,没有固定页码,自定义从偏移量开始往后查询自定义条数
# pagination_class = pagination.LimitOffsetPagination
# 游标分页器
# pagination_class = pagination.CursorPagination
# 过滤组件:实际开发,有多个过滤条件时,要把优先级高的放在前面
filter_backends = [SearchFilter, OrderingFilter, CountFilter] # 搜索,排序,过滤
# filter_backends = [OrderingFilter]
# 参与搜索的字段
search_fields = ['name', 'id']
# 允许排序的字段
ordering_fields = ['id', 'price']
自定义过滤组件
"""
自定义过滤器
1)自定义类实现filter_queryset方法即可,接收request, queryset, view参数
2)制定过滤条件,将过滤成功后的queryset返回即可,如果过滤失败,返回原样的queryset
3)将自定义过滤类配置给群查视图类的filter_backends
"""
filters.py
# 前台接口:/course/free/?count=2 ,代表只对前台返回2条数据
class CountFilter:
def filter_queryset(self, request, queryset, view):
count = request.query_params.get('count', None)
try:
# TODO: 切片后的queryset不能再做ORM Q查询,如何实现queryset切片,现在再过滤时后配置
# 结论:drf的搜索组件和排序组件都是建立在表的所有数据基础上的过滤规则,所以该自定义过滤类在视图类配置中
# filter_backends = [SearchFilter, OrderingFilter, CountFilter] 必须在前两者之后
return queryset[:int(count)]
except:
return queryset
Django-filter 过滤插件
安装
>: pip install django-filter
分类过滤
pip install django-filter
前台访问:
# http://127.0.0.1:8000/course/free/?course_category=2
"""
方式一
1)在视图文件views.py中导入django-filter的功能组件
from django_filters.rest_framework import DjangoFilterBackend
2)将搜索组件配置给群查接口视图类的filter_backends
filter_backends = [DjangoFilterBackend]
3)配置视图类关联的Model表可以分类的字段(通常是可以分组的字段)
filter_fields = ['course_category']
4)前台访问该群查接口,采用拼接参数方式用分类course_category字段将分类条件提供给后台
http://127.0.0.1:8000/course/free/?course_category=1 # 拿课程分类1下的所有课程
方式二(可以自定义)
1)自定义过滤类继承django-filter插件的FilterSet类,绑定Model表,并设置分类字段
from django_filters.filterset import FilterSet
from . import models
class CourseFilterSet(FilterSet):
class Meta:
model = models.Course
fields = ['course_category']
2)在视图文件views.py中导入django-filter的功能组件及自定义的过滤类
from django_filters.rest_framework import DjangoFilterBackend
from .filters import CourseFilterSet
3)将搜索组件配置给群查接口视图类的filter_backends
filter_backends = [DjangoFilterBackend]
4)配置视图类关联的自定义过滤类
filter_class = CourseFilterSet
5)前台访问该群查接口,采用拼接参数方式用分类course_category字段将分类条件提供给后台
http://127.0.0.1:8000/course/free/?course_category=1 # 拿课程分类1下的所有课程
"""
区间过滤
"""
1)自定义过滤类继承django-filter插件的FilterSet类,绑定Model表,并设置自定义区间规则字段
from django_filters.filterset import FilterSet
from . import models
class CourseFilterSet(FilterSet):
# 区间过滤:field_name关联的Model字段;lookup_expr设置规则;gt是大于,gte是大于等于;
min_price = filters.NumberFilter(field_name='price', lookup_expr='gte')
max_price = filters.NumberFilter(field_name='price', lookup_expr='lte')
class Meta:
model = models.Course
fields = ['min_price', 'max_price']
2)在视图文件views.py中导入django-filter的功能组件及自定义的过滤类
from django_filters.rest_framework import DjangoFilterBackend
from .filters import CourseFilterSet
3)将搜索组件配置给群查接口视图类的filter_backends
filter_backends = [DjangoFilterBackend]
4)配置视图类关联的自定义过滤类
filter_class = CourseFilterSet
5)前台访问该群查接口,采用拼接参数方式用自定义区间规则字段将区间条件提供给后台
http://127.0.0.1:8000/course/free/?min_price=30&max_price=60 # 拿课程价格在30~60的所有课程
"""
views.py 过滤使用
# http://127.0.0.1:8000/course/free/?min_price=30&max_price=60
from .filters import CourseFilterSet
class CourseViewSet(GenericViewSet, ListModelMixin):
queryset = models.Course.objects.filter(is_delete=False, is_show=True).all()
serializer_class = serializers.CourseSerializer
# 过滤组件:实际开发,有多个过滤条件时,要把优先级高的放在前面
filter_backends = [DjangoFilterBackend]
# 分类字段 方式一
# filter_fields = ['course_category'] # model中的已有字段
# 配置视图类关联的自定义过滤类 方式二
filter_class = CourseFilterSet # 写好的类
有分页、搜索、排序、自定义过滤的课程群查接口
views.py 分页、搜索、排序、过滤器 功能融合
# 分页组件:基础分页(采用)、偏移分页、游标分页(了解)
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
from . import pagination
# 过滤组件:搜索功能、排序功能
from rest_framework.filters import SearchFilter, OrderingFilter
from .filters import CountFilter
class CourseViewSet(GenericViewSet, ListModelMixin):
queryset = models.Course.objects.filter(is_delete=False, is_show=True).all()
serializer_class = serializers.CourseSerializer
# 分页组件
# 方法一:直接使用drf分页类,在视图类中完成分页类的必要配置
# pagination_class = PageNumberPagination
# PageNumberPagination.page_size = 1
# 方法二:自定义分页类继承drf分页类,在自定义分页类中完成配置,视图类中使用自定义分页类
# 基础分页器
# pagination_class = pagination.PageNumberPagination
# 偏移分页器,没有固定页码,自定义从偏移量开始往后查询自定义条数
# pagination_class = pagination.LimitOffsetPagination
# 游标分页器
# pagination_class = pagination.CursorPagination
# 过滤组件:实际开发,有多个过滤条件时,要把优先级高的放在前面
filter_backends = [SearchFilter, OrderingFilter, CountFilter]
# 参与搜索的字段
search_fields = ['name', 'id']
# 允许排序的字段
ordering_fields = ['id', 'price']
选择了IT,必定终身学习