GenericView方法实现商品列表页和分页功能
class GoodListView(mixins.ListModelMixin, generics.GenericAPIView):
class GoodsListView(generics.ListAPIView):
分页setting中配置:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
}
# 取消setting中配置
class StandardResultsSetPagination(PageNumberPagination):
page_size = 20
page_size_query_param = 'page_size'
page_query_param = 'p'
max_page_size = 100
view中加入
pagination_class = StandardResultsSetPagination # 此参数及功能在GenericApiView中
viewset
1.重写了 as_view方法,使注册url更加简单。
2.动态设置serializer时的action
绑定方法1
goods_list = GoodsListViewset.as_view({
'get': 'list',
})
方法二(后期用法)
router.register('goods', GoodsListViewset)
path('', include(router.urls)), # 此处为空字符串,切记
view之间的继承关系,最后一个view属于django
GenericViewSet
GenericAPIView 配合mixin组合成了很多功能类
APIView
View
mixins和genericviewset增加view功能
drf的request和response
过滤
类中必须重载queryset,如果queryset为None就会报错
django自带的过滤
queryset = Goods.objects.all()
serializer_class = GoodsSerializer
pagination_class = StandardResultsSetPagination # 此参数及功能在GenericApiView中
def get_queryset(self):
price_min = self.request.query_params.get('price_min', 0)
if price_min:
self.queryset = self.queryset.filter(shop_price__gt=price_min)
return self.queryset
drf过滤
django_filter
install_app
rest_framework配置 或者对特定的view设置
drf的过滤器简单使用
from django_filters.rest_framework import DjangoFilterBackend
filter_backends = (DjangoFilterBackend,)
filter_fields = ('name', 'shop_price')
较高级使用(新建filters文件)
class GoodsFilter(filters.FilterSet):
min_price = filters.NumberFilter(field_name="shop_price", lookup_expr='gte')
max_price = filters.NumberFilter(field_name="shop_price", lookup_expr='lte')
class Meta:
model = Goods
fields = ['name', 'min_price', 'max_price']
view中:
filter_class = GoodsFilter
搜索和排序
在上文新建的filters中简单模糊搜索:关键词lookup应该跟数据库查询关键字相关,不确定
name = filters.CharFilter(field_name="name", lookup_expr='icontains')
drf自带的search_filter: 可以采用类似正则表达式的方法(排序类似)
from rest_framework import filters
filter_backends = (DjangoFilterBackend, filters.SearchFilter)
search_fields = ('name', 'goods_brief', 'goods_desc')
The search behavior may be restricted by prepending various characters to the search_fields.
'^' Starts-with search.
'=' Exact matches.
'@' Full-text search. (Currently only supported Django's MySQL backend.)
'$' Regex search.
category层级结构序列化
class CategorySerializer3(serializers.ModelSerializer):
class Meta:
model = GoodsCategory
fields = '__all__'
class CategorySerializer2(serializers.ModelSerializer):
sub_cat = CategorySerializer3(many=True)
class Meta:
model = GoodsCategory
fields = '__all__'
class CategorySerializer(serializers.ModelSerializer):
sub_cat = CategorySerializer2(many=True)
class Meta:
model = GoodsCategory
fields = '__all__'
django跨域的问题 =>
pip install django-cors-headers
install_app -> corsheaders
midware -> 'corsheaders.middleware.CorsMiddleware', # 跨域问题
CORS_ORIGIN_ALLOW_ALL = True
https://github.com/ottoyiu/django-cors-headers
价格筛选过程中前后端的参数需要一致,否则会出错。
用户登录和手机注册
drf的token登录和原理
前后端不分离的带有csrf验证,如果采用前后端分离不方便带csrf_code方法
install_app中: 'rest_framework.authtoken' # token
makemageration->magerate->数据表迁移
url配置
from rest_framework.authtoken import views
path('api-token-auth', views.obtain_auth_token),
chorme的servistate插件:用于测试url的返回数据等功能
此时POST http://127.0.0.1:8000/api-token-auth (用户数据)->就能返回token
采用token验证
django默认采用session登录机制?
写入类似Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b的http header。
setting中的REST_FRAMEWORK加入tokenauth拦截器。(此方法用于测试,全局的,测试完要删除。)
实际开发中将token拦截写入类中,防止公共页面的权限不够。
middleware拦截机制,重载process_request&process_response
drf token的问题, 存储在服务器,分布式服务器要多处存储,没设置过期时间。
viewset配置认证类
from rest_framework.authentication import TokenAuthentication
authentication_classes = (TokenAuthentication, ) # 类内配置用户
JSON WEB TOKEN (一个规范)
好处:采用加密解密算法在服务器端运行验证,无需再存入数据库,增加速度,减少验证时的服务器负载。
jwt介绍 7-4
使用jwt进行认证
pip install djangorestframework-jwt
setting中rest_framework配置:(实际开发时在类中加入,不在全局加入) 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
from rest_framework_jwt.views import obtain_jwt_token
# jwt的认证接口
path('jwt-auth', obtain_jwt_token),
网友评论