对queryset 序列化一般 继承两个类 serializers.Seriailzer 和 serializers.ModelSerializer
models.py
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=32,unique=True, null=False)
desc = models.TextField()
create_time = models.DateTimeField(auto_now_add=True)
is_show = models.BooleanField(default=1)
author=models.ForeignKey(to='UserInfo',on_delete=models.CASCADE,default=1)
class Meta:
db_table = 'article'
class UserInfo(models.Model):
USER_TYPE = (
(1,'普通用户'),
(2,'VIP'),
(3,'SVIP')
)
user_type = models.IntegerField(choices=USER_TYPE)
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
class UserToken(models.Model):
user = models.OneToOneField(UserInfo,on_delete=models.CASCADE)
token = models.CharField(max_length=64)
serializers.py
# 一 *****序列化相关
# Serializer 序列化的字段需要自己定义
# ModelSerializer 可以在 Meta里面fields = ‘__all__’ 序列化所有
# 序列化都是不能 对外键关系进行更深层次的序列化
# 如果需要序列化外键所关联对象 需要在继承 ModelSelrialzer 中 添加 depth=1
class Meta:
fields='__all__'
model = 'xxxxx'
depth = 1 将会学序列化外键数据 如果是 2 将会序列化外键的外键数据
# 所以我们需要有时需要返回 一种所需要的数据结构就需要重构
# 1 在类中显示的声明你需要序列化的字段名称 再用 def get_名称(self,obj) -->obj为每当前对象
# 2 重写 to_representation方法 在super().to_representation 中找到你需要修改的参数进行修改
# 以上两种方法都需要返回一个 序列化之后的数据
# 二 ******数据校验相关
# 在继承序列化类中可进行 数据验证类似于 Django的Form组件
from rest_framework import serializers
from app1.models import Article, UserInfo
class UserSerializer(serializers.Serializer):
#username=serializers.CharField(source='username') 错误写法 不能重复指定
username=serializers.CharField()
password=serializers.CharField()
user_type=serializers.CharField()
article=serializers.SerializerMethodField()
# 修改了article返回的数据 如不修改默认返回 数据库原有的数据 就是int类型的数据
# 第一种 重构数据 的方法
def get_article(self,obj):
res=obj.article_set.all()
serializer=ArticleSerializer(instance=res,many=True)
return serializer.data
class User2Serializer(serializers.ModelSerializer):
class Meta:
model = UserInfo
fields='__all__'
class ArticleSerializer(serializers.ModelSerializer):
# author=serializers.SerializerMethodField()
class Meta:
model = Article
fields="__all__"
# def get_author(self,obj):
# # data=UserSerializer(instance=obj.author,many=False).data # 一开始这样写发现报栈
# 溢出后来返现原来是写了个死循环 --相互序列化 低级错误
# res=User2Serializer(obj.author).data
# return res
# 第二种 重构返回数据的 方法 instance 就是当前被序列化的对象
def to_representation(self, instance):
data=super().to_representation(instance)
data['author']=User2Serializer(instance=instance.author,many=False).data
return data
class UserTokenSerializer(serializers.Serializer):
token=serializers.CharField()
username=serializers.CharField(source='user.username') # 指定查询数据库中的字段
一 、局部认证
在当前类中添加
class XXX(APIView):
authentication_classes=[你写的认证类]
pass
认证类推荐继承 BasicAuthentication
例子
from rest_framework.authentication import BaseAuthentication
from rest_framework import exception
class UserAuth(BaseAuthentication):
# 必须重写以下两个方法
def authenticate(self,request):
token=request.query_params.get('id')
# 用户没通过认证 --一般抛异常
if not token:
raise exception.AuthenticationFailed({'code':900,'msg':‘认证失败’})
# 认证通过 需返回两个值 一个是user 一个是token
user_obj=通过查数据库得到
return user_obj,token ----其实是 request.user=user_obj (全局)
def authenticate_header(self, request):
pass
二 、全局认证
settings中配置
REST_FRAMEWORK={
'DEFAULT_AUTHENTICATION_CLASSES':(你写的认证类路径 不能写在views中,) --这可以为一个元祖或可迭代对象
}
和认证差不多,但是使用权限的前提必须要使用认证 这个想想就知道了 ("Authentication credentials were not provided.")
一、局部权限认证
class XXX(APIView):
permission_classes
推荐继承 BasicPermission
from rest_framework.permissions import BasePermission
from rest_framework import exceptions
exceptions.PermissionDenied
class UserPermission(BasePermission):
# 看一下源码就知道要重写什么方法
def has_permission(self,request,view):
权限处理逻辑
return True #认证通过
return False # 没过
二、全局权限认证
在settings中配置
REST_FRAMEWORK={
'DEFAULT_PERMISSION_CLASSES':(你写的权限类路径 不能写在views中,) --这可以为一个元祖或可迭代对象
}
第一种写法 继承BaseThrottle
from rest_framework.throttling import BaseThrottle
vist_data = {}
# 定义一个类 (你要写限制的类)
class VisitThrottle(BaseThrottle):
'''匿名用户60s只能访问三次(根据ip)''
history = None
def allow_request(self, request, view):
cur_time = time.time()
identify = self.get_ident(request)
if identify not in vist_data:
vist_data[identify] = []
vist_data[identify].append(cur_time)
return True
res = vist_data[identify]
self.history = res
if res:
if res[-1] + 60 > cur_time:
if len(res) < 3:
res.insert(0, cur_time)
return True
return False
else:
res.pop()
return True
else:
res.append(cur_time)
return True
# 超过访问次数之后的 可访问剩余时间
def wait(self):
return 60 - (time.time() - self.history[-1])
第二种继承SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):
#
# # 什么都不需要重写 只需要定义一个 scope 和 get_cache_key 返回当前身份
scope = 'NBA' # 继承BaseThrottle 是不需要scope
#
#
# def get_cache_key(self, request, view):
# # 通过ip限制节流
# return self.get_ident(request)
settgins.py
'DEFAULT_THROTTLE_CLASSES': ('utils.throttle.VisitThrottle',),
# 继承SimpleRateThrottle 必须做以下配置
"DEFAULT_THROTTLE_RATES":{
'NBA':'5/m', #没登录用户3/m,NBA就是scope定义的值
'NBAUser':'3/m', #登录用户10/m,NBAUser就是scope定义的值
# NBA 和NBAUser 可以使不同的APIView 使用不同的节流方式
}
第一种方式
class Pager1View(APIView):
def get(self,request,*args,**kwargs):
#获取所有数据
roles = models.Role.objects.all()
#创建分页对象
pg = PageNumberPagination()
#获取分页的数据
page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
#对数据进行序列化
ser = PagerSerialiser(instance=page_roles,many=True)
return Response(ser.data)
settings.py 一定要配置分页 否则返回 [ ]
REST_FRAMEWORK={
"PAGE_SIZE":2 # 每页数量
}
第二种方式 自定义分页类继承
#自定义分页类
class MyPageNumberPagination(PageNumberPagination):
#每页显示多少个
page_size = 3
#默认每页显示3个,可以通过传入pager1/?page=2&size=4,改变默认每页显示的个数
page_size_query_param = "size"
#最大页数不超过10
max_page_size = 10
#获取页码数的
page_query_param = "page"
class Pager1View(APIView):
def get(self,request,*args,**kwargs):
#获取所有数据
roles = models.Role.objects.all()
#创建分页对象,这里是自定义的MyPageNumberPagination
pg = MyPageNumberPagination()
#获取分页的数据
page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
#对数据进行序列化
ser = PagerSerialiser(instance=page_roles,many=True)
return Response(ser.data)
原文链接 http://www.cnblogs.com/derek1184405959/p/8727595.html