zoukankan      html  css  js  c++  java
  • django之认证权限和接口

    认证组件

    0.token

    #login视图中认证和token 的存储
    class Login(APIView):
        authentication_classes = []
        def post(self,request):
            response={'code':100,'msg':'登录成功'}
            name=request.data.get('name')
            pwd=request.data.get('pwd')
            try:
                #get 有且只有一条才不报错,其他都抛异常
                user=models.User.objects.filter(name=name,pwd=pwd).get()
                #登录成功,需要去token表中存数据
                #生成一个唯一的idhg
                token=uuid.uuid4()
                models.Token.objects.update_or_create(user=user,defaults={'token':token})
                response['token']=token
            except ObjectDoesNotExist as e:
                response['code']=101
                response['msg']='用户名或密码错误'
            except Exception as e:
                response['code'] = 102
                # response['msg'] = '未知错误'
                response['msg'] = str(e)
            return Response(response)

    1.写一个认证类,继承BaseAuthentication

    
    

      from rest_framework.authentication import BaseAuthentication
      from app01 import models
      from rest_framework.exceptions import AuthenticationFailed
      from rest_framework.permissions import BasePermission


    class
    MyAuth(BaseAuthentication): def authenticate(self,request): #写一些认证的逻辑 token=request.GET.get('token') token_obj=models.Token.objects.filter(token=token).first() if token_obj: #有值表示登录了 #token_obj.user 当前登录的user对象 return token_obj.user,token_obj else: #没有值,表示没有登录,抛异常 raise AuthenticationFailed('您没有登录')

    -局部使用

      在视图类中写一个列表

      authentication_classes=[Myauth,]

    -全局使用

      在settings.py中配置

      REST_FRAMEWORK={"DEFAULT_AUTHENTICATION_CLASSES":["app01.MyAuths.MyAuth",]}

    -局部禁用

      在视图中写入authentication_classes = []

    -源码中可以观察到的点

      -如果在项目的setting.py中配置了REST_FRAMEWORK,默认先从项目的setting中取
      -如果取不到,才去默认的drf(djangorestframework)配置文件中取
      -如果用户在视图类中配置了,先去用户配置的取

    -总结

      先取视图类中配置的----》项目setting中取----》默认配置

    接口创建前置工作

    先在models.py中创建好数据库字段模型(只针对我下面的代码)

    from django.db import models
    
    # Create your models here.
    class Book(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        publish_date = models.DateField(null=True)
        xx=models.IntegerField(choices=((0,'文学类'),(1,'情感类')),default=1,null=True)
        publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE,null=True)
        authors=models.ManyToManyField(to='Author')
        def __str__(self):
            return self.name
        def test(self):
            return 'xxx'
    
    
    class Author(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        age = models.IntegerField()
    
    
    
    class Publish(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        city = models.CharField(max_length=32)
        email = models.EmailField()
    
        def __str__(self):
            return self.name

    在views中导入需要的序列化组件

    from django.shortcuts import render
    from rest_framework.response import Response
    from  rest_framework import serializers
    from managements import models
    from rest_framework.views import  APIView
    # Create your views here.
    class PublishSerializers(serializers.ModelSerializer):
        class Meta:
            model=models.Publish
            fields='__all__'

    方法一:基本视图方法

    基本视图
    class PublishView(APIView):
    
        def get(self, request):
            publish_list = models.Publish.objects.all()
            bs = PublishSerializers(publish_list, many=True)
            # 序列化数据
    
            return Response(bs.data)
    
        def post(self, request):
            # 添加一条数据
            print(request.data)
    
            bs=PublishSerializers(data=request.data)
            if bs.is_valid():
                bs.save()  # 生成记录
                return Response(bs.data)
            else:
    
                return Response(bs.errors)
    
    class PublishDetailView(APIView):
        def get(self,request,pk):
            publish_obj=models.Publish.objects.filter(pk=pk).first()
            bs=PublishSerializers(publish_obj,many=False)
            return Response(bs.data)
        def put(self,request,pk):
            publish_obj = models.Publish.objects.filter(pk=pk).first()
    
            bs=PublishSerializers(data=request.data,instance=publish_obj)
            if bs.is_valid():
                bs.save() # update
                return Response(bs.data)
            else:
                return Response(bs.errors)
        def delete(self,request,pk):
            models.Publish.objects.filter(pk=pk).delete()
    
            return Response("")

    方法二:基于mixins来封装的视图

    基于mixins来封装的视图
    from rest_framework.mixins import CreateModelMixin,ListModelMixin,RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin
    from rest_framework.generics import GenericAPIView
    
    class PublishView(CreateModelMixin,ListModelMixin,GenericAPIView):
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializers
        def post(self,request, *args, **kwargs):
            return self.create(request, *args, **kwargs)
        def get(self,request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    
    class PublishDetailView(RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin,GenericAPIView):
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializers
        def get(self,request, *args, **kwargs):
            return self.retrieve(request, *args, **kwargs)
        def put(self,request, *args, **kwargs):
            return self.update(request, *args, **kwargs)
        def delete(self,request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)

    方法三:通过封装好的方法两个类来完成

    from rest_framework.generics import CreateAPIView,ListCreateAPIView,DestroyAPIView,RetrieveUpdateDestroyAPIView
    class PublishView(ListCreateAPIView):
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializers
    
    class PublishDetailView(RetrieveUpdateDestroyAPIView):
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializers

    方法四:一个类完成五种方法

    from django.views import View
    from rest_framework.viewsets import ModelViewSet
    class PublishView(ModelViewSet):
        queryset=models.Publish.objects.all()
        serializer_class=PublishSerializers
    
    
    from rest_framework.viewsets import  ViewSetMixin
    from rest_framework.views import  APIView
    # ViewSetMixin 重写了as_view方法
    class Test(ViewSetMixin,APIView):
    
        def aaa(self,request):
            return Response({'code':100})

    类的继承关系图

  • 相关阅读:
    【强烈推荐】 超漂亮的仿腾讯弹出层效果(兼容主流浏览器<转>;
    必须掌握的八个【cmd 命令行】
    grep命令的用法
    sed 命令的用法1
    Paste命令的用法
    uniq命令的用法
    join命令的用法
    Sort命令的用法
    cut命令的用法
    tr命令学习
  • 原文地址:https://www.cnblogs.com/xuxingping/p/11129095.html
Copyright © 2011-2022 走看看