restful

restful

在这里插入图片描述

	一个url路由 对应一个功能,操作,绝大多数的操作都是针对数据库的增删改查
	前后端分离,都是ajax axios,所有的接口都是接收json,返回json
	Api 接口是提供给程序访问的 ,提供了权限和限流认证
	restful 携带token 需要在请求头中  用键值对的方式携带token
	可以通过restful-jwt 提供的认证视图来处理 用户认证

认证和权限
可以自定义权限类视图 需继承BasePermission权限类
进入IsAuthenticated 更改认证条件

class MyPermission(BasePermission):
	def has_permission(self,request,view):
		return bool(request.user and request.user.is_superuser)

权限和限流

在 app.urls中配置路由
from rest_framework_jwt.views import obtain_jwt_token
 path('login/', obtain_jwt_token)
在settings.py中配置 权限认证配置
REST_FRAMEWORK = {
	# 限流限制
    'DEFAULT_THROTTLE_RATES': {
        'user': '10/hour',
        'anon': '5/day'
    },
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication'  # 接口的认证器
    ]
}
JWT_AUTH = {
    'JWT_PAYLOAD_HANDLER': 'rest_framework_jwt.utils.jwt_payload_handler',
    # headers中 Authorization键对应的值得前缀 类似于 : jwt xxxxxx
    'JWT_AUTH_HEADER_PREFIX': 'JWT',
    # 有效期7天
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
    # 允许刷新
    'JWT_ALLOW_REFRESH': True,
    # token在24小时过期
    'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(hours=24)
}
permission_classes = (AllowAny,)  # 处理权限的类 ,允许所有人访问
permission_classes = (IsAuthenticated,)  # 处理权限的类 ,允许认证用户访问
throttle_classes = [AnonRateThrottle] # 处理接口的限流

在settings.py中配置限流次数
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES':{
        'user':'10/hour',
        'anon':'5/day'
    }
}
# 函数视图
def book_view(request):
    if request.method == 'GET':
        books = BookInfo.objects.all()
        book_list = []
        for book in books:
            # 组装数据
            book_data = {
                'id': book.id,
                'btitle': book.btitle,
                'bpub_date': book.bpub_date,
                'bread': book.bread,
                'bcomment': book.bcomment
            }
            book_list.append(book_data)
        return JsonResponse(book_list, safe=False)
    if request.method == 'POST':
        # 从请求获取数据
        btitle = request.POST.get('btitle')
        bpub_date = request.POST.get('bpub_date')
        bread = request.POST.get('bread')
        bcomment = request.POST.get('bcomment')
        if all([btitle, bpub_date]):
            pass
        else:
            return JsonResponse({'code': 400, 'msg': '缺少参数'})
        # 根据数据创建模型
        book = BookInfo.objects.create(btitle=btitle, bpub_date=bpub_date)
        # 校验数据
        book.save()
        # 组装数据
        book_data = {
            'id': book.id,
            'btitle': book.btitle,
            'bpub_date': book.bpub_date,
            'bread': book.bread,
            'bcomment': book.bcomment
        }
        return JsonResponse(book_data)

# 类视图
class BookView(View):
    def get(self, request):
        books = BookInfo.objects.all()
        book_list = []
        for book in books:
            # 组装数据
            book_data = {
                'id': book.id,
                'btitle': book.btitle,
                'bpub_date': book.bpub_date,
                'bread': book.bread,
                'bcomment': book.bcomment
            }
            book_list.append(book_data)
        return JsonResponse(book_list, safe=False)

    def post(self, request):

        # # 从请求获取数据
        # btitle = request.POST.get('btitle')
        # bpub_date = request.POST.get('bpub_date')
        # bread = request.POST.get('bread')
        # bcomment = request.POST.get('bcomment')
        # 从body中获取数据
        data = json.loads(request.body.decode())
        btitle = data.get('btitle')
        bpub_date = data.get('bpub_date')
        if all([btitle, bpub_date]):
            pass
        else:
            return JsonResponse({'code': 400, 'msg': '缺少参数'})
        # 根据数据创建模型
        book = BookInfo.objects.create(btitle=btitle, bpub_date=bpub_date)
        book.save()
        book_data = {
            'id': book.id,
            'btitle': book.btitle,
            'bpub_date': book.bpub_date,
            'bread': book.bread,
            'bcomment': book.bcomment
        }
        return JsonResponse(book_data)

# APIView
class BookAPIView(APIView):
    # permission_classes = (AllowAny,)  # 处理权限的类 ,允许所有人访问
    permission_classes = (IsAuthenticated,)  # 处理权限的类 ,允许认证用户访问
    throttle_classes = [AnonRateThrottle] # 处理接口的限流
    def get(self, request):
        books = BookInfo.objects.all()
        book_list = []
        for book in books:
            # 组装数据
            book_data = {
                'id': book.id,
                'btitle': book.btitle,
                'bpub_date': book.bpub_date,
                'bread': book.bread,
                'bcomment': book.bcomment
            }
            book_list.append(book_data)
        return Response(book_list)

    def post(self, request):

        # 从body中获取数据

        btitle = request.data.get('btitle')
        bpub_date = request.data.get('bpub_date')
        if all([btitle, bpub_date]):
            pass
        else:
            return Response({'code': 400, 'msg': '缺少参数'})
        # 根据数据创建模型
        book = BookInfo.objects.create(btitle=btitle, bpub_date=bpub_date)
        book.save()
        book_data = {
            'id': book.id,
            'btitle': book.btitle,
            'bpub_date': book.bpub_date,
            'bread': book.bread,
            'bcomment': book.bcomment
        }
        return Response(book_data)

序列化器

	如果使用serializers.Serializer 需要 字段名和模型中的字段名一致
	写入时需重写create方法
	当读取和写入数据共用一个序列化器时需要将写入不需要的字段添加 read_only = True
 class BookSerializer(serializers.Serializer):
     """
     字段名必须是模型中的字段名
     """
     id = serializers.IntegerField(read_only=True)
     btitle = serializers.CharField()
     bpub_date = serializers.DateField()
     bread = serializers.IntegerField(read_only=True)
     bcomment = serializers.IntegerField(read_only=True)

     def create(self, validated_data):
         book = BookInfo(btitle=validated_data.get('btitle'), bpub_date=validated_data.get('bpub_date'))
         book.save()
         return book

使用serializers.ModelSerializer 模型序列化器时 只需指定需要序列化的model 和字段

class HeroWriteSerializer(serializers.ModelSerializer):
    class Meta:
        model = HeroInfo
        # fields = '__all__' # 所有字段
        # fields = ['id', 'btitle', 'bpub_date', 'bread', 'bcomment', 'is_delete'] # 指定要哪些字段
        exclude = ['is_delete']

# 序列化数据  字符串  json
# 结构化数据   二维表,表,model

# 结构化 => 序列化 只需要指定 把结构化数据中的字段序列化
# 序列化 => 结构化 1.校验,数据是否符合结构需求。2.校验通过,把数据放在结构中(model) model.save()

模型序列化器外键所在表关联查询
使用 depth 深入序列化即可

class HeroSerializer(serializers.ModelSerializer):
    class Meta:
        model = HeroInfo
        depth = 1  # 深入序列化一层
        fields = '__all__'  # 所有字段

主表反向查询子表数据

class BookHeroSerializer(serializers.ModelSerializer):
    class Meta:
        model = HeroInfo
        exclude = ['hbook', 'is_delete']


class BookSerializer(serializers.ModelSerializer):
    # 英雄信息同时读取
    # 能序列化的内容,是模型所有的属性内容
    # book = BookInfo()
    # book.heroinfo_set

    heroinfo_set = BookHeroSerializer(many=True)

    class Meta:
        model = BookInfo
        fields = '__all__'  # 所有字段
        # fields = ['id', 'btitle', 'bpub_date', 'bread', 'bcomment', 'is_delete'] # 指定要哪些字段
        # exclude = ['is_delete']

处理器
返回加工后的结果 或者报错

class BookWriteSerializer(serializers.ModelSerializer):
    # 处理器=>  返回处理后的结果,   或者报错
    def validate_btitle(self, data):
        # 可以加工书名
        # 验证书籍名, 条件: 不能是一个字
        if len(data) > 1:
            pass
        else:
            # raise serializers.ValidationError('书名不能是一个字') # 报错
            return data+data # 加工
        return data

    class Meta:
        model = BookInfo
        fields = '__all__'  # 所有字段

校验器 处理结果 1.不报错 2.报错

# 校验器 处理结果 1.不报错 2.报错
def btitle_validator(data):
    if len(data) > 1:
        pass
    else:
        raise serializers.ValidationError('书名不能是一个字')  # 报错

def btitle_validator2(data):
    if len(data) < 10:
        pass
    else:
        raise serializers.ValidationError('书名不能超过10个字')  # 报错


class BookWriteSerializer(serializers.ModelSerializer):
    btitle = serializers.CharField(max_length=20, validators=[btitle_validator,btitle_validator2])
    # validators 里面全是校验器,校验器函数,处理结果

    class Meta:
        model = BookInfo
        fields = '__all__'  # 所有字段

同时校验两个数据

class BookWriteSerializer(serializers.ModelSerializer):
    # 同时校验多个数据
    def validate(self, dates):
        pw = dates.get('pw')
        pw2 = dates.get('pw2')
        if pw == pw2:
            pass
        else:
            raise serializers.ValidationError('两次密码不一致')  # 报错
        return dates

    class Meta:
        model = BookInfo
        fields = '__all__'  # 所有字段
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值