• Book接口


    Book系列连表接口

    from django.shortcuts import render
    
    # Create your views here.
    from rest_framework.views import APIView
    from rest_framework.viewsets import ModelViewSet
    from app01.models import Book
    # from app01.ser import BookSerializers
    from rest_framework.decorators import action
    from rest_framework.response import Response
    from rest_framework.authentication import SessionAuthentication, BasicAuthentication
    # class TestView(APIView):
    #     def get(self,request):
    #         1/0
    #         return Response({'msg':'个人中心'})
    #
    # class BookViewSet(ModelViewSet):
    #     authentication_classes = [BasicAuthentication,]
    #     queryset = Book.objects.all()
    #     serializer_class = BookSerializers
        # @action(methods=['get'], detail=False)
        # def login(self, request):
        #     Book.objects.update_or_create()
        #     return Response({'msg':'登陆成功'})
        # @action(methods=['put'], detail=True)
        # def get_new_5(self, request,pk):
        #     return Response({'msg':'获取5条数据成功'})
    
    from rest_framework.permissions import AllowAny,IsAuthenticated,IsAdminUser,IsAuthenticatedOrReadOnly
    
    
    
    from app01.response import APIResponse
    from app01 import models
    from app01 import ser as serializers
    class PublishAPIView(APIView):
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            if pk:
                publish_obj = models.Publish.objects.filter(pk=pk).first()
                if not publish_obj:
                    return APIResponse(1, 'pk error', http_status=400)
                publish_data = serializers.PublishModelSerializer(publish_obj).data
                return APIResponse(results=publish_data)
    
            publish_query = models.Publish.objects.all()
            return APIResponse(0, 'ok', data=serializers.PublishModelSerializer(publish_query, many=True).data)
    
    
    class BookAPIView(APIView):
        # 单查、群查
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            if pk:
                book_obj = models.Book.objects.filter(pk=pk, is_delete=False).first()
                if not book_obj:
                    return APIResponse(1, 'pk error', http_status=400)
                book_data = serializers.BookModelSerializer(book_obj).data
                print(book_data)
                return APIResponse(data=book_data)
    
            book_query = models.Book.objects.filter(is_delete=False).all()
    
            return APIResponse(0, 'ok', data=serializers.BookModelSerializer(book_query, many=True).data)
    
        # 单删、群删
        def delete(self, request, *args, **kwargs):
            """
            单删:前台数据为pk,接口为 /books/(pk)/
            群删:前台数据为pks,接口为 /books/
            """
            pk = kwargs.get('pk')
            # 将单删群删逻辑整合
            if pk:  # /books/(pk)/的接口就不考虑群删,就固定为单删
                pks = [pk]
            else:
                pks = request.data.get('pks')
            # 前台数据有误(主要是群删没有提供pks)
            if not pks:
                return APIResponse(1, 'delete error', http_status=400)
            # 只要有操作受影响行,就是删除成功,反之失败
            rows = models.Book.objects.filter(is_delete=False, pk__in=pks).update(is_delete=True)
            if rows:
                return APIResponse(0, 'delete ok')
            return APIResponse(1, 'delete failed')
    
        # 单增、群增
        def post(self, request, *args, **kwargs):
            """
            单增:前台提交字典,接口 /books/
            群增:前台提交列表套字典,接口 /books/
            """
            request_data = request.data
            if isinstance(request_data, dict):  # 单增
                book_ser = serializers.BookModelSerializer(data=request_data)
                if book_ser.is_valid():
                    book_obj = book_ser.save()
                    return APIResponse(data=serializers.BookModelSerializer(book_obj).data)
    return APIResponse(1, msg=book_ser.errors)
    elif isinstance(request_data, list) and len(request_data) != 0 :  # 群增
                book_ser = serializers.BookModelSerializer(data=request_data, many=True)
                book_ser.is_valid(raise_exception=True)
                book_obj_list = book_ser.save()
    return APIResponse(data=serializers.BookModelSerializer(book_obj_list, many=True).data)
    else:
    return APIResponse(1, 'data error', http_status=400)
    
    # 单整体改、群整体改
    defput(self, request, *args, **kwargs):
    """
            单整体改:前台提交字典,接口 /books/(pk)/
            群整体改:前台提交列表套字典,接口 /books/,注每一个字典都可以通过pk
            """
            pk = kwargs.get('pk')
            request_data = request.data
    if pk: # 单改
    try:
                    book_obj = models.Book.objects.get(pk=pk)
    except:
    return APIResponse(1, 'pk error')
    
    # 修改和新增,都需要通过数据,数据依旧给data,修改与新增不同点,instance要被赋值为被修改对象
                book_ser = serializers.BookModelSerializer(instance=book_obj, data=request_data)
                book_ser.is_valid(raise_exception=True)
                book_obj = book_ser.save()
    return APIResponse(data=serializers.BookModelSerializer(book_obj).data)
    else:  # 群改
    ifnot isinstance(request_data, list) or len(request_data) == 0:
    return APIResponse(1, 'data error', http_status=400)
    
    # [{pk:1,...}, {pk:3,...}, {pk:100,...}] => [obj1, obj3, obj100] + [{...}, {...}, {...}]
    # 要考虑pk对应的对象是否被删,以及pk没有对应的对象
    # 假设pk3被删,pk100没有 => [obj1] + [{...}]
    
    # 注:一定不要在循环体中对循环对象进行增删(影响对象长度)的操作
                obj_list = []
                data_list = []
    for dic in request_data:
    # request_data可能是list,单内部不一定是dict
    try:
                        pk = dic.pop('pk')
    try:
                            obj = models.Book.objects.get(pk=pk, is_delete=False)
                            obj_list.append(obj)
                            data_list.append(dic)
    except:
    pass
    except:
    return APIResponse(1, 'data error', http_status=400)
    
                book_ser = serializers.BookModelSerializer(instance=obj_list, data=data_list, many=True)
                book_ser.is_valid(raise_exception=True)
                book_obj_list = book_ser.save()
    return APIResponse(data=serializers.BookModelSerializer(book_obj_list, many=True).data)
    
    # 单局部改、群局部改
    defpatch(self, request, *args, **kwargs):
    """
            单整体改:前台提交字典,接口 /books/(pk)/
            群整体改:前台提交列表套字典,接口 /books/,注每一个字典都可以通过pk
            """
            pk = kwargs.get('pk')
            request_data = request.data
    if pk:
    try:
                    book_obj = models.Book.objects.get(pk=pk)
    except:
    return APIResponse(1, 'pk error')
    # 局部修改就是在整体修改基础上设置partial=True,将所有参与反序列化字段设置为required=False
                book_ser = serializers.BookModelSerializer(instance=book_obj, data=request_data, partial=True)
                book_ser.is_valid(raise_exception=True)
                book_obj = book_ser.save()
    return APIResponse(data=serializers.BookModelSerializer(book_obj).data)
    
    else:  # 群改
    ifnot isinstance(request_data, list) or len(request_data) == 0:
    return APIResponse(1, 'data error', http_status=400)
    
    # [{pk:1,...}, {pk:3,...}, {pk:100,...}] => [obj1, obj3, obj100] + [{...}, {...}, {...}]
    # 要考虑pk对应的对象是否被删,以及pk没有对应的对象
    # 假设pk3被删,pk100没有 => [obj1] + [{...}]
    
    # 注:一定不要在循环体中对循环对象进行增删(影响对象长度)的操作
                obj_list = []
                data_list = []
    for dic in request_data:
    # request_data可能是list,单内部不一定是dict
    try:
                        pk = dic.pop('pk')
    try:
                            obj = models.Book.objects.get(pk=pk, is_delete=False)
                            obj_list.append(obj)
                            data_list.append(dic)
    except:
    pass
    except:
    return APIResponse(1, 'data error', http_status=400)
    
                book_ser = serializers.BookModelSerializer(instance=obj_list, data=data_list, many=True, partial=True)
                book_ser.is_valid(raise_exception=True)
                book_obj_list = book_ser.save()
    return APIResponse(data=serializers.BookModelSerializer(book_obj_list, many=True).data)
    
    classAuthorAPIView(APIView):
    defget(self,request,*args,**kwargs):
            authors=models.Author.objects.all()
            author_ser=serializers.AuthorModelSerializer(authors,many=True)
    return APIResponse(data=author_ser.data)
    defput(self,reuqest,*args,**kwargs):
    pass
    defpost(self,request,*args,**kwargs):
            author_ser=serializers.AuthorModelSerializer(data=request.data)
            author_ser.is_valid(raise_exception=True)
            author_ser.save()
    return APIResponse()
    defdelete(self,request,*args,**kwargs):
    pass
    views.py
    from rest_framework import serializers
    from app01 import models
    class BookListSerializer(serializers.ListSerializer):
        # 1、create方法父级ListSerializer已经提供了
        # def create(self, validated_data):
        #     # 通过self.child来访问绑定的ModelSerializer
        #     print(self.child)
        #     raise Exception('我不提供')
    
        # 2、父级ListSerializer没有通过update方法的实现体,需要自己重写
        def update(self, instance, validated_data):
            # print(instance)
            # print(validated_data)
            return [
                self.child.update(instance[i], attrs) for i, attrs in enumerate(validated_data)
            ]
    
    
    
    class BookModelSerializer(serializers.ModelSerializer):
        # 通过BookModelSerializer.Meta.list_serializer_class来访问绑定的ListSerializer
        class Meta:
            # 关联ListSerializer完成群增群改
            list_serializer_class = BookListSerializer
    
            model = models.Book
            # fields = ('name', 'price', 'publish', 'authors')
            # fields = ('name', 'price', 'publish_name', 'author_list')
    
            # 了解
            # fields = '__all__'
            # exclude = ('id', )
            # depth = 1
    
            # 序列化与反序列化整合
            fields = ('name', 'price', 'publish_name', 'author_list', 'publish', 'authors')
            extra_kwargs = {
                'publish': {
                    'write_only': True
                },
                'authors': {
                    'write_only': True
                }
            }
    
    
    
    
    # 前提:如果只有查需求的接口,自定义深度还可以用子序列化方式完成
    class PublishModelSerializer(serializers.ModelSerializer):
        # 子序列化都是提供给外键(正向方向)完成深度查询的,外键数据是唯一:many=False;不唯一:many=True
        # 注:只能参与序列化,且反序列化不能写(反序列化外键字段会抛异常)
        books = BookModelSerializer(many=True)
        class Meta:
            model = models.Publish
            fields = ('name', 'address', 'books')
    
    class AuthorModelSerializer(serializers.ModelSerializer):
        class Meta:
            model=models.Author
            fields=('name','sex','mobile','mobile_in')
            extra_kwargs={
                'mobile':{
                    'read_only': True
                },
            }
    
        mobile_in=serializers.CharField(write_only=True)
        # def validate_mobile_in(self, data):
        #     print(data)
        #     return data
    
    
        def create(self, validated_data):
            print(validated_data)
            mobile=validated_data.pop('mobile_in')
            author=models.Author.objects.create(**validated_data)
            authordetail=models.AuthorDetail.objects.create(mobile=mobile,author=author)
            return author
    ser.py
    from django.db import models
    
    
    
    # 一、基表
    # Model类的内部配置Meta类要设置abstract=True,这样的Model类就是用来作为基表
    
    # 多表:Book,Publish,Author,AuthorDetail
    class BaseModel(models.Model):
        is_delete = models.BooleanField(default=False)
        create_time = models.DateTimeField(auto_now_add=True)
        class Meta:
            # 基表必须设置abstract,基表就是给普通Model类继承使用的,设置了abstract就不会完成数据库迁移完成建表
            abstract = True
    
    class Book(BaseModel):
        name = models.CharField(max_length=16)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        publish = models.ForeignKey(to='Publish', related_name='books', db_constraint=False, on_delete=models.DO_NOTHING)
        # 重点:多对多外键实际在关系表中,ORM默认关系表中两个外键都是级联
        # ManyToManyField字段不提供设置on_delete,如果想设置关系表级联,只能手动定义关系表
        authors = models.ManyToManyField(to='Author', related_name='books', db_constraint=False)
            
        # 自定义连表深度,不需要反序列化,因为自定义插拔属性不参与反序列化
        @property
        def publish_name(self):
            return self.publish.name
        @property
        def author_list(self):
            temp_author_list = []
            for author in self.authors.all():
                temp_author_list.append({
                    'name': author.name,
                    'sex': author.get_sex_display(),
                    'mobile': author.detail.mobile
                })
            return temp_author_list
    
    
    class Publish(BaseModel):
        name = models.CharField(max_length=16)
        address = models.CharField(max_length=64)
    
    class Author(BaseModel):
        name = models.CharField(max_length=16)
        sex = models.IntegerField(choices=[(0, ''),(1, '')], default=0)
    
    class AuthorDetail(BaseModel):
        mobile = models.CharField(max_length=11)
        # 有作者可以没有详情,删除作者,详情一定会被级联删除
        # 外键字段为正向查询字段,related_name是反向查询字段
        author = models.OneToOneField(to='Author', related_name='detail', db_constraint=False, on_delete=models.CASCADE)
    
    # 二、表断关联
    # 1、表之间没有外键关联,但是有外键逻辑关联(有充当外键的字段)
    # 2、断关联后不会影响数据库查询效率,但是会极大提高数据库增删改效率(不影响增删改查操作)
    # 3、断关联一定要通过逻辑保证表之间数据的安全
    # 4、断关联
    # 5、级联关系
    #       作者没了,详情也没:on_delete=models.CASCADE
    #       出版社没了,书还是那个出版社出版:on_delete=models.DO_NOTHING
    #       部门没了,员工没有部门(空不能):null=True, on_delete=models.SET_NULL
    #       部门没了,员工进入默认部门(默认值):default=0, on_delete=models.SET_DEFAULT
    
    
    # 三、ORM外键设计
    # 1、一对多:外键放在多的一方
    # 2、多对多:外键放在常用的一方
    # 3、一对一:外键放在不常用的一方
    # 4、外键字段为正向查询字段,related_name是反向查询字段
    
    
    # from django.contrib.auth.models import AbstractUser, User
    # class MyUser(AbstractUser):
    #     pass
    models.py
    LANGUAGE_CODE = 'zh-hans'
    
    TIME_ZONE = 'Asia/shanghai'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = False
    setting.py
    path(r'publishes/', views.PublishAPIView.as_view()),
    re_path(r'^publishes/(?P<pk>d+)/$', views.PublishAPIView.as_view()),
    
    path(r'books/', views.BookAPIView.as_view()),
    re_path(r'^books/(?P<pk>d+)/$', views.BookAPIView.as_view()),
    urls.py

    RBAC-基于角色的访问控制

    一 什么是RBAC

    RBAC  是基于角色的访问控制(Role-Based Access Control )在 RBAC  中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。

    应用:
    # RBAC - Role-Based Access Control
    # Django的 Auth组件 采用的认证规则就是RBAC
    
    # 1)像专门做人员权限管理的系统(CRM系统)都是公司内部使用,所以数据量都在10w一下,一般效率要求也不是很高
    # 2)用户量极大的常规项目,会分两种用户:前台用户(三大认证) 和 后台用户(BRAC来管理)
    # 结论:没有特殊要求的Django项目可以直接采用Auth组件的权限六表,不需要自定义六个表,也不需要断开表关系,单可能需要自定义User表
    
    
    前后台权限控制:
    # 1)后台用户对各表操作,是后台项目完成的,我们可以直接借助admin后台项目(Django自带的)
    # 2)后期也可以用xadmin框架来做后台用户权限管理
    
    # 3)前台用户的权限管理如何处理
    #   定义了一堆数据接口的视图类,不同的登录用户是否能访问这些视图类,能就代表有权限,不能就代表无权限
    #   前台用户权限用drf框架的 三大认证

    二 Django的内置RBAC(六表)

    权限三表

    权限三表

    权限六表

    权限六表

    三 实操

    from django.db import models
    
    from django.contrib.auth.models import AbstractUser
    class User(AbstractUser):
        mobile = models.CharField(max_length=11, unique=True)
    
        def __str__(self):
            return self.username
    
    
    class Book(models.Model):
        name = models.CharField(max_length=64)
    
        def __str__(self):
            return self.name
    
    
    class Car(models.Model):
        name = models.CharField(max_length=64)
    
        def __str__(self):
            return self.name
    models.py
    from . import models
    
    from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
    
    # 自定义User表后,admin界面管理User类
    class UserAdmin(DjangoUserAdmin):
        # 添加用户课操作字段
        add_fieldsets = (
            (None, {
                'classes': ('wide',),
                'fields': ('username', 'password1', 'password2', 'is_staff', 'mobile', 'groups', 'user_permissions'),
            }),
        )
        # 展示用户呈现的字段
        list_display = ('username', 'mobile', 'is_staff', 'is_active', 'is_superuser')
    
    
    admin.site.register(models.User, UserAdmin)
    admin.site.register(models.Book)
    admin.site.register(models.Car)
    admin.py

    这样就可以登陆到admin后台进行操作了

    drfdemo

    from django.contrib import admin
    from django.urls import path
    
    from app01 import views
    from rest_framework.routers import DefaultRouter
    
    
    router = DefaultRouter()  # 可以处理视图的路由器
    router.register('books', views.BooksViewSet)  # 向路由器中注册视图集
    
      # 将路由器中的所以路由信息追到到django的路由列表中
    from django.views.decorators.csrf import csrf_exempt
    urlpatterns = [
        path('admin/', admin.site.urls),
    
        # path('tset/', csrf_exempt(views.test)),
    
    
        path('books1/', views.Books.as_view()),  #在这个地方应该写个函数内存地址
    
    
        path('booksapiview/', views.BooksAPIView.as_view()),  #在这个地方应该写个函数内存地址
    
    ]
    #这是什么意思?两个列表相加
    # router.urls  列表
    urlpatterns += router.urls
    urls.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)
        author=models.CharField(max_length=32)
    models.py
    from rest_framework.serializers import ModelSerializer
    from app01.models import  Book
    class BookModelSerializer(ModelSerializer):
        class Meta:
            model = Book
            fields = "__all__"
    ser.py
    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    
    
    
    from rest_framework.viewsets import ModelViewSet
    from .models import Book
    from .ser import BookModelSerializer
    
    from django.views import View
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework.request import Request
    
    class BooksViewSet(ModelViewSet):
        queryset = Book.objects.all()
        serializer_class = BookModelSerializer
    
    
    class Books(View):
        #如果有个需求,只能接受get请求
        http_method_names = ['get',]
        def get(self,request):
            print(self.request)
            return HttpResponse('ok')
    
    class BooksAPIView(APIView):
    
        def get(self,request):
            # request 已经不是原生django的request了,是drf自己定义的request对象
            # print(request._request)
            # print(request.data)
            print(request.method)
            print(request.query_params)  #get请求,地址中的参数
            # 原来在
            print(request.GET)
            return HttpResponse('ok')
    
        def post(self,request):
    
            print(request.data) # urlencoded方式有数据,json格式也有,formdata也有数据
            print(type(request.POST)) # 原生的POST
            print(request._request.POST)
    
            from django.http.request import QueryDict
    
    
            return HttpResponse('ok')
    views.py

    drf_serializer

    class MyResponse():
        def __init__(self):
            self.status=100
            self.msg='成功'
        @property
        def get_dict(self):
            return self.__dict__
    
    
    if __name__ == '__main__':
        res=MyResponse()
        res.status=101
        res.msg='查询失败'
        # res.data={'name':'lqz'}
        print(res.get_dict)
    utils.py
    # from rest_framework.serializers import Serializer  # 就是一个类
    from rest_framework import serializers
    from rest_framework.exceptions import ValidationError
    # 需要继承 Serializer
    from app01.models import Book
    
    def check_author(data):
        if data.startswith('sb'):
            raise ValidationError('作者名字不能以sb开头')
        else:
            return data
    
    
    class BookSerializer(serializers.Serializer):
        id=serializers.CharField(read_only=True)
        name=serializers.CharField(max_length=16,min_length=4)
        # price=serializers.DecimalField()
        price=serializers.CharField(write_only=True,required=True)
        author=serializers.CharField(validators=[check_author])  # validators=[] 列表中写函数内存地址
        publish=serializers.CharField()
    
        def validate_price(self, data):   # validate_字段名  接收一个参数
            #如果价格小于10,就校验不通过
            # print(type(data))
            # print(data)
            if float(data)>10:
                return data
            else:
                #校验失败,抛异常
                raise ValidationError('价格太低')
        def validate(self, validate_data):   # 全局钩子
            print(validate_data)
            author=validate_data.get('author')
            publish=validate_data.get('publish')
            if author == publish:
                raise ValidationError('作者名字跟出版社一样')
            else:
                return validate_data
        def update(self, instance, validated_data):
            #instance是book这个对象
            #validated_data是校验后的数据
            instance.name=validated_data.get('name')
            instance.price=validated_data.get('price')
            instance.author=validated_data.get('author')
            instance.publish=validated_data.get('publish')
            instance.save()  #book.save()   django 的orm提供的
            return instance
        def create(self, validated_data):
            instance=Book.objects.create(**validated_data)
            return instance
            # Book.objects.create(name=validated_data.get('name'))
    
    
    class BookModelSerializer(serializers.ModelSerializer):
        class Meta:
            model=Book  # 对应上models.py中的模型
            fields='__all__'
            # fields=('name','price','id','author') # 只序列化指定的字段
            # exclude=('name',) #跟fields不能都写,写谁,就表示排除谁
            # read_only_fields=('price',)
            # write_only_fields=('id',) #弃用了,使用extra_kwargs
            extra_kwargs = {  # 类似于这种形式name=serializers.CharField(max_length=16,min_length=4)
                'price': {'write_only': True},
            }
    
    
    
    
    
    from rest_framework import serializers
    
    
    class BookSerializer(serializers.Serializer):
        # book.publish
        # book.price
        # book.xxx--->book.title
        # book.authors.all
    
        xxx=serializers.CharField(source='title')
        price=serializers.CharField()
        pub_date=serializers.CharField(source='test')
        publish=serializers.CharField(source='publish.email')
        # book.publish.email  相当于
        # authors=serializers.CharField()
        authors=serializers.SerializerMethodField() #它需要有个配套方法,方法名叫get_字段名,返回值就是要显示的东西
        def get_authors(self,instance):
            # book对象
            authors=instance.authors.all()  # 取出所有作者
            ll=[]
            for author in authors:
                ll.append({'name':author.name,'age':author.age})
            return ll
    ser.py
    from django.shortcuts import render
    
    # Create your views here.
    from django.http import JsonResponse
    
    from rest_framework.views import APIView
    from app01.models import Book
    from app01.ser import BookSerializer
    from app01.ser import BookModelSerializer
    from rest_framework.response import Response  #drf 提供的响应对象
    
    # 导入自己写的response类
    from app01.utils import MyResponse
    class BookView(APIView):
        def get(self,request,pk):
            book=Book.objects.filter(id=pk).first()
            #用一个类,毫无疑问,一定要实例化
            #要序列化谁,就把谁传过来
            book_ser=BookSerializer(book)  # 调用类的__init__
            # book_ser.data   序列化对象.data就是序列化后的字典
            return Response(book_ser.data)
            # return JsonResponse(book_ser.data)
    
        def put(self,request,pk):
            response_msg={'status':100,'msg':'成功'}
            # 找到这个对象
            book = Book.objects.filter(id=pk).first()
            # 得到一个序列化类的对象
            # boo_ser=BookSerializer(book,request.data)
            boo_ser=BookSerializer(instance=book,data=request.data)
    
            # 要数据验证(回想form表单的验证)
            if boo_ser.is_valid():  # 返回True表示验证通过
                boo_ser.save()  # 报错
                response_msg['data']=boo_ser.data
            else:
                response_msg['status']=101
                response_msg['msg']='数据校验失败'
                response_msg['data']=boo_ser.errors
    
            return Response(response_msg)
    
        def delete(self,request,pk):
            response=MyResponse()
            ret=Book.objects.filter(pk=pk).delete()
            return Response(response.get_dict)
    
    class BooksView(APIView):
        # def get(self,request):
        #     response_msg = {'status': 100, 'msg': '成功'}
        #     books=Book.objects.all()
        #     book_ser=BookSerializer(books,many=True)  #序列化多条,如果序列化一条,不需要写
        #     response_msg['data']=book_ser.data
        #     return Response(response_msg)
    
        def get(self,request):
            response=MyResponse()
            books=Book.objects.all()
            book_ser=BookSerializer(books,many=True)  #序列化多条,如果序列化一条,不需要写
            response.data=book_ser.data
            return Response(response.get_dict)
    
        # 新增
        def post(self,request):
            response_msg = {'status': 100, 'msg': '成功'}
            #修改才有instance,新增没有instance,只有data
            book_ser = BookSerializer(data=request.data)
            # book_ser = BookSerializer(request.data)  # 这个按位置传request.data会给instance,就报错了
            # 校验字段
            if book_ser.is_valid():
                book_ser.save()
                response_msg['data']=book_ser.data
            else:
                response_msg['status']=102
                response_msg['msg']='数据校验失败'
                response_msg['data']=book_ser.errors
            return Response(response_msg)
    
    
    class BooksView2(APIView):
        def get(self,request):
            response=MyResponse()
            books=Book.objects.all()
            book=Book.objects.all().first()
            book_ser=BookModelSerializer(books,many=True)
            book_one_ser=BookModelSerializer(book)
            print(type(book_ser))
            print(type(book_one_ser))
            response.data=book_ser.data
            return Response(response.get_dict)
    
    
    
    
    from rest_framework.views import APIView
    from app02.models import Book
    from app02.ser import BookSerializer
    from rest_framework.response import Response  #drf 提供的响应对象
    
    class APP02BookView(APIView):
        def get(self,request,pk):
            book=Book.objects.filter(id=pk).first()
            book_ser=BookSerializer(book)
            return Response(book_ser.data)
    views.py
    from django.db import models
    
    # Create your models here.
    
    class Book(models.Model):
        title=models.CharField(max_length=32)
        price=models.IntegerField()
        pub_date=models.DateField()
        publish=models.ForeignKey("Publish",on_delete=models.CASCADE,null=True)
        authors=models.ManyToManyField("Author")
        def __str__(self):
            return self.title
        def test(self):
            return 'lqz is big'
    
    class Publish(models.Model):
        name=models.CharField(max_length=32)
        email=models.EmailField()
        # def __str__(self):
        #     return self.name+'ccccc'
    
    class Author(models.Model):
        name=models.CharField(max_length=32)
        age=models.IntegerField()
        def __str__(self):
            return self.name
    models.py

    drf_views

    from django.contrib import admin
    from django.urls import path,re_path
    from app01 import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('test/', views.TestView.as_view()),
        path('test2/', views.TestView2.as_view()),
        path('books/', views.BookView.as_view()),
        re_path('books/(?P<pk>d+)', views.BookDetailView.as_view()),
    
        # 使用GenericAPIView重写的
        path('books2/', views.Book2View.as_view()),
        re_path('books2/(?P<pk>d+)', views.Book2DetailView.as_view()),
    
        # 使用GenericAPIView+5 个视图扩展类  重写的
        path('books3/', views.Book3View.as_view()),
        re_path('books3/(?P<pk>d+)', views.Book3DetailView.as_view()),
    
        #
        path('books4/', views.Book4View.as_view()),
        re_path('books4/(?P<pk>d+)', views.Book4DetailView.as_view()),
    
        # 使用ModelViewSet编写5个接口
        path('books5/', views.Book5View.as_view(actions={'get':'list','post':'create'})), #当路径匹配,又是get请求,会执行Book5View的list方法
        re_path('books5/(?P<pk>d+)', views.Book5View.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})),
    
    
        #继承ViewSetMixin的视图类,路由可以改写成这样
        path('books6/', views.Book6View.as_view(actions={'get': 'get_all_book'})),
    ]
    urls.py
    #这个变量REST_FRAMEWORK,里面都是drf的配置信息
    REST_FRAMEWORK = {
        'DEFAULT_RENDERER_CLASSES': (  # 默认响应渲染类
            'rest_framework.renderers.JSONRenderer',  # json渲染器
            'rest_framework.renderers.BrowsableAPIRenderer',  # 浏览API渲染器
        ),
    
    }
    settings.py
    from django.db import models
    
    # Create your models here.
    
    
    class Book(models.Model):
        name=models.CharField(max_length=32)
        price=models.DecimalField(max_digits=5,decimal_places=2)
        publish=models.CharField(max_length=32)
    
    
    class Publish(models.Model):
        name=models.CharField(max_length=32)
        email=models.CharField(max_length=32)
    models.py
    from rest_framework import serializers
    from app01.models import Book,Publish
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model=Book
            fields='__all__'
    
    class PublishSerializer(serializers.ModelSerializer):
        class Meta:
            model=Publish
            fields='__all__'
    ser.py
    from django.shortcuts import render
    
    # Create your views here.
    
    from rest_framework.request import Request
    from rest_framework.response import Response
    from rest_framework.views import  APIView
    
    from rest_framework import status
    from rest_framework.renderers import JSONRenderer
    class TestView(APIView):
        renderer_classes=[JSONRenderer,]
        def get(self,request):
            print(request)
    
            return Response({'name':'lqz'},status=status.HTTP_200_OK,headers={'token':'xxx'})
    
    class TestView2(APIView):
        def get(self,request):
            print(request)
    
            return Response({'name':'2222'},status=status.HTTP_200_OK,headers={'token':'xxx'})
    
    ##################################视图相关
    from rest_framework.generics import GenericAPIView
    from app01.models import Book
    from app01.ser import BookSerializer
    # 基于APIView写的
    class BookView(APIView):
        def get(self,request):
            book_list=Book.objects.all()
            book_ser=BookSerializer(book_list,many=True)
    
            return Response(book_ser.data)
        def post(self,request):
            book_ser = BookSerializer(data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response({'status':101,'msg':'校验失败'})
    
    
    class BookDetailView(APIView):
        def get(self, request,pk):
            book = Book.objects.all().filter(pk=pk).first()
            book_ser = BookSerializer(book)
            return Response(book_ser.data)
    
        def put(self, request,pk):
            book = Book.objects.all().filter(pk=pk).first()
            book_ser = BookSerializer(instance=book,data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response({'status': 101, 'msg': '校验失败'})
    
        def delete(self,request,pk):
            ret=Book.objects.filter(pk=pk).delete()
            return Response({'status': 100, 'msg': '删除成功'})
    
    # 基于GenericAPIView写的
    class Book2View(GenericAPIView):
        #queryset要传queryset对象,查询了所有的图书
        # serializer_class使用哪个序列化类来序列化这堆数据
        queryset=Book.objects
        # queryset=Book.objects.all()
        serializer_class = BookSerializer
        def get(self,request):
            book_list=self.get_queryset()
            book_ser=self.get_serializer(book_list,many=True)
    
            return Response(book_ser.data)
        def post(self,request):
            book_ser = self.get_serializer(data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response({'status':101,'msg':'校验失败'})
    
    
    class Book2DetailView(GenericAPIView):
        queryset = Book.objects
        serializer_class = BookSerializer
        def get(self, request,pk):
            book = self.get_object()
            book_ser = self.get_serializer(book)
            return Response(book_ser.data)
    
        def put(self, request,pk):
            book = self.get_object()
            book_ser = self.get_serializer(instance=book,data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response({'status': 101, 'msg': '校验失败'})
    
        def delete(self,request,pk):
            ret=self.get_object().delete()
            return Response({'status': 100, 'msg': '删除成功'})
    
    
    ## 基于GenericAPIView写的Publish的5个接口
    from app01.models import Publish
    from app01.ser import PublishSerializer
    class Publish2View(GenericAPIView):
        #queryset要传queryset对象,查询了所有的图书
        # serializer_class使用哪个序列化类来序列化这堆数据
        queryset=Publish.objects
        # queryset=Book.objects.all()
        serializer_class = PublishSerializer
        def get(self,request):
            book_list=self.get_queryset()
            book_ser=self.get_serializer(book_list,many=True)
    
            return Response(book_ser.data)
        def post(self,request):
            book_ser = self.get_serializer(data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response({'status':101,'msg':'校验失败'})
    
    
    class Publish2DetailView(GenericAPIView):
        queryset = Publish.objects
        serializer_class = PublishSerializer
        def get(self, request,pk):
            book = self.get_object()
            book_ser = self.get_serializer(book)
            return Response(book_ser.data)
    
        def put(self, request,pk):
            book = self.get_object()
            book_ser = self.get_serializer(instance=book,data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response({'status': 101, 'msg': '校验失败'})
    
        def delete(self,request,pk):
            ret=self.get_object().delete()
            return Response({'status': 100, 'msg': '删除成功'})
    
    # CURD:create update,delet,retrieve
    
    # 5 个视图扩展类
    from rest_framework.mixins import  ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin
    
    class Book3View(GenericAPIView,ListModelMixin,CreateModelMixin):
    
        queryset=Book.objects
        serializer_class = BookSerializer
        def get(self,request):
            return self.list(request)
    
        def post(self,request):
            return self.create(request)
    
    class Book3DetailView(GenericAPIView,RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin):
        queryset = Book.objects
        serializer_class = BookSerializer
        def get(self, request,pk):
            return self.retrieve(request,pk)
    
        def put(self, request,pk):
            return self.update(request,pk)
    
        def delete(self,request,pk):
            return self.destroy(request,pk)
    
    
    
    #GenericAPIView的视图子类 9个
    from rest_framework.generics import CreateAPIView,ListAPIView,UpdateAPIView,RetrieveAPIView,DestroyAPIView,ListCreateAPIView,RetrieveUpdateDestroyAPIView,RetrieveDestroyAPIView,RetrieveUpdateAPIView
    
    # class Book4View(ListAPIView,CreateAPIView):  #获取所有,新增一个
    class Book4View(ListCreateAPIView):  #获取所有,新增一个
        queryset = Book.objects
        serializer_class = BookSerializer
    
    # class Book4DetailView(UpdateAPIView,RetrieveAPIView,DestroyAPIView):
    class Book4DetailView(RetrieveUpdateDestroyAPIView):
        queryset = Book.objects
        serializer_class = BookSerializer
    
    
    
    # 使用ModelViewSet编写5个接口
    from rest_framework.views import APIView
    from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet
    class Book5View(ModelViewSet):  #5个接口都有,但是路由有点问题
        queryset = Book.objects
        serializer_class = BookSerializer
    
    
    
    class Book5View(ReadOnlyModelViewSet):  #2个接口,获取一条,和获取所有两个
        queryset = Book.objects
        serializer_class = BookSerializer
    
    
    from rest_framework.viewsets import ViewSetMixin
    
    class Book6View(ViewSetMixin,APIView): #一定要放在APIVIew前
    
    
        def get_all_book(self,request):
            print("xxxx")
            book_list = Book.objects.all()
            book_ser = BookSerializer(book_list, many=True)
            return Response(book_ser.data)
    views.py

    drf_router_auth

    REST_FRAMEWORK={
        "DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",]
    }
    settings.py
    from django.contrib import admin
    from django.urls import path,re_path
    from app01 import views
    
    # 第一步:导入routers模块
    from rest_framework import routers
    # 第二步:有两个类,实例化得到对象
    # routers.DefaultRouter 生成的路由更多
    # routers.SimpleRouter
    router=routers.SimpleRouter()
    # 第三步:注册
    # router.register('前缀','继承自ModelViewSet视图类','别名')
    router.register('books',views.BookViewSet) # 不要加斜杠了
    
    # 第四步
    # router.urls # 自动生成的路由,加入到原路由中
    # print(router.urls)
    # urlpatterns+=router.urls
    '''
    [
    <URLPattern '^books/$' [name='book-list']>, 
    <URLPattern '^books/(?P<pk>[^/.]+)/$'[name='book-detail']>
    ]
    
    '''
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('login/', views.LoginView.as_view()),
        path('test/', views.TestView.as_view()),
        # path('books/', views.BookViewSet.as_view({'get':'list','post':'create'})),
        # re_path('books/(?P<pk>d+)', views.BookViewSet.as_view({'get':'retrieve','put':'update','delete':'destroy'})),
    
    ]
    
    urlpatterns+=router.urls
    
    
    
    '''
    SimpleRouter
    <URLPattern '^books/$' [name='book-list']>, 
    <URLPattern '^books/(?P<pk>[^/.]+)/$'[name='book-detail']>
    
    
    DefaultRouter
    ^books/$ [name='book-list']
    ^books/(?P<pk>[^/.]+)/$ [name='book-detail']  这两条跟simple一样
    
    ^$ [name='api-root']  根,根路径会显示出所有可以访问的地址
    ^.(?P<format>[a-z0-9]+)/?$ [name='api-root']
    
    
    ^books.(?P<format>[a-z0-9]+)/?$ [name='book-list']  http://127.0.0.1:8000/books.json
    ^books/(?P<pk>[^/.]+).(?P<format>[a-z0-9]+)/?$ [name='book-detail']  http://127.0.0.1:8000/books/1.json
    
    
    '''
    urls.py
    from django.shortcuts import render
    
    # Create your views here.
    from rest_framework.viewsets import ModelViewSet
    from rest_framework.response import  Response
    from rest_framework.decorators import action  # 装饰器
    
    from app01.models import Book
    from app01.ser import BookSerializer
    from rest_framework.request import Request
    from rest_framework.authentication import BaseAuthentication
    
    from rest_framework.exceptions import AuthenticationFailed
    from app01.app_auth import MyAuthentication
    from rest_framework.views import APIView
    from rest_framework.response import Response
    import uuid
    from app01 import models
    
    class BookViewSet(ModelViewSet):
        # authentication_classes=[MyAuthentication]
        queryset =Book.objects.all()
        serializer_class = BookSerializer
        # methods第一个参数,传一个列表,列表中放请求方式,
        # ^books/get_1/$ [name='book-get-1'] 当向这个地址发送get请求,会执行下面的函数
        # detail:布尔类型 如果是True
        #^books/(?P<pk>[^/.]+)/get_1/$ [name='book-get-1']
        @action(methods=['GET','POST'],detail=True)
        def get_1(self,request,pk):
            print(request.user.username)
            print(pk)
            book=self.get_queryset()[:2]  # 从0开始截取一条
            ser=self.get_serializer(book,many=True)
            return Response(ser.data)
    
    
    
    
    from rest_framework.authentication import BasicAuthentication
    class TestView(APIView):
        def get(self,request):
            print(request.user.username)
            return Response({'msg':'我是测试'})
    
    
    class LoginView(APIView):
        authentication_classes = []
        def post(self,request):
            username=request.data.get('username')
            password=request.data.get('password')
            user=models.User.objects.filter(username=username,password=password).first()
            if user:
                # 登陆成功,生成一个随机字符串
                token=uuid.uuid4()
                # 存到UserToken表中
                # models.UserToken.objects.create(token=token,user=user)# 用它每次登陆都会记录一条,不好,如有有记录
                # update_or_create有就更新,没有就新增
                models.UserToken.objects.update_or_create(defaults={'token':token},user=user)
                return Response({'status':100,'msg':'登陆成功','token':token})
            else:
                return Response({'status': 101, 'msg': '用户名或密码错误'})
    views.py
    from rest_framework import serializers
    from app01.models import Book
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model=Book
            fields='__all__'
    ser.py
    from django.db import models
    
    # Create your models here.
    class Book(models.Model):
        name=models.CharField(max_length=32)
        price=models.DecimalField(max_digits=5,decimal_places=2)
        publish=models.CharField(max_length=32)
    
    
    class User(models.Model):
        username=models.CharField(max_length=32)
        password=models.CharField(max_length=32)
        user_type=models.IntegerField(choices=((1,'超级用户'),(2,'普通用户'),(3,'二笔用户')))
    
    class UserToken(models.Model):
        token=models.CharField(max_length=64)
        user=models.OneToOneField(to=User,on_delete=models.CASCADE)  #一对一关联到User表
    models.py
    from rest_framework.authentication import BaseAuthentication
    from rest_framework.exceptions import AuthenticationFailed
    from app01.models import UserToken
    class MyAuthentication(BaseAuthentication):
        def authenticate(self, request):
            # 认证逻辑,如果认证通过,返回两个值
            #如果认证失败,抛出AuthenticationFailed异常
            token=request.GET.get('token')
            if  token:
                user_token=UserToken.objects.filter(token=token).first()
                # 认证通过
                if user_token:
                    return user_token.user,token
                else:
                    raise AuthenticationFailed('认证失败')
            else:
                raise AuthenticationFailed('请求地址中需要携带token')
    app_auth.py

    drf_others

    from django.contrib import admin
    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('login/', views.LoginView.as_view()),
        path('test/', views.TestView.as_view()),
        path('test2/', views.TestView2.as_view()),
        path('test3/', views.TestView3.as_view()),
        path('test4/', views.TestView4.as_view()),
        path('test5/', views.TestView5.as_view()),
        path('test6/', views.TestView6.as_view()),
        path('books/', views.BookView.as_view()),
        path('books2/', views.Book2View.as_view()),
        path('test7/', views.TestView7.as_view()),
    ]
    urls.py
    REST_FRAMEWORK = {
        # "DEFAULT_AUTHENTICATION_CLASSES": ["app01.app_auth.MyAuthentication", ],
        # 'DEFAULT_PERMISSION_CLASSES': [
        #     'app01.app_auth.UserPermission',
        # ],
        # 'DEFAULT_THROTTLE_CLASSES': (
        #     'rest_framework.throttling.AnonRateThrottle',
        # ),
    
        'DEFAULT_THROTTLE_CLASSES': (
            'rest_framework.throttling.AnonRateThrottle',
            'rest_framework.throttling.UserRateThrottle'
        ),
        'DEFAULT_THROTTLE_RATES': {
            'user': '10/m',
            'anon': '5/m',
        },
        'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
    'EXCEPTION_HANDLER': 'app01.app_auth.my_exception_handler',
    
    }
    settings.py
    from rest_framework.authentication import BaseAuthentication
    from rest_framework.exceptions import AuthenticationFailed
    from app01.models import UserToken
    class MyAuthentication(BaseAuthentication):
        def authenticate(self, request):
            # 认证逻辑,如果认证通过,返回两个值
            #如果认证失败,抛出AuthenticationFailed异常
            token=request.GET.get('token')
            if  token:
                user_token=UserToken.objects.filter(token=token).first()
                # 认证通过
                if user_token:
                    return user_token.user,token
                else:
                    raise AuthenticationFailed('认证失败')
            else:
                raise AuthenticationFailed('请求地址中需要携带token')
    
    
    
    from rest_framework.permissions import BasePermission
    
    class UserPermission(BasePermission):
        def  has_permission(self, request, view):
            # 不是超级用户,不能访问
            # 由于认证已经过了,request内就有user对象了,当前登录用户
            user=request.user  # 当前登录用户
            # 如果该字段用了choice,通过get_字段名_display()就能取出choice后面的中文
            print(user.get_user_type_display())
            if user.user_type==1:
                return True
            else:
                return False
    
    
    
    
    
    # 自定义异常处理的方法
    from rest_framework.views import exception_handler
    from rest_framework.response import Response
    from rest_framework import status
    def my_exception_handler(exc, context):
        response=exception_handler(exc, context)
        # 两种情况,一个是None,drf没有处理
        #response对象,django处理了,但是处理的不符合咱们的要求
        # print(type(exc))
    
        if not response:
            if isinstance(exc, ZeroDivisionError):
                return Response(data={'status': 777, 'msg': "除以0的错误" + str(exc)}, status=status.HTTP_400_BAD_REQUEST)
            return Response(data={'status':999,'msg':str(exc)},status=status.HTTP_400_BAD_REQUEST)
        else:
            # return response
            return Response(data={'status':888,'msg':response.data.get('detail')},status=status.HTTP_400_BAD_REQUEST)
    
    
    #自己封装Response对象
    
    from rest_framework.response import Response
    
    # return APIResponse(100,'成功',data)
    
    class APIResponse(Response):
        def __init__(self,code=100,msg='成功',data=None,status=None,headers=None,**kwargs):
            dic = {'code': code, 'msg': msg}
            if  data:
                dic = {'code': code, 'msg': msg,'data':data}
            dic.update(kwargs)
            super().__init__(data=dic, status=status,headers=headers)
    app_auth.py
    from django.db import models
    
    # Create your models here.
    from django.db import models
    
    # Create your models here.
    class Book(models.Model):
        name=models.CharField(max_length=32)
        price=models.DecimalField(max_digits=5,decimal_places=2)
        publish=models.CharField(max_length=32)
    
    
    class User(models.Model):
        username=models.CharField(max_length=32)
        password=models.CharField(max_length=32)
        user_type=models.IntegerField(choices=((1,'超级用户'),(2,'普通用户'),(3,'二笔用户')))
    
    class UserToken(models.Model):
        token=models.CharField(max_length=64)
        user=models.OneToOneField(to=User,on_delete=models.CASCADE)  #一对一关联到User表
    models.py
    from rest_framework import serializers
    from app01.models import Book
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model=Book
            fields='__all__'
    ser.py

    drf_books_ser

    from rest_framework import serializers
    from api import models
    
    
    #写一个类,继ListSerializer,重写update
    class BookListSerializer(serializers.ListSerializer):
        # def create(self, validated_data):
        #     print(validated_data)
        #     return super().create(validated_data)
        def update(self, instance, validated_data):
            print(instance)
            print(validated_data)
            # 保存数据
            # self.child:是BookModelSerializer对象
            # ll=[]
            # for i,si_data in enumerate(validated_data):
            #     ret=self.child.update(instance[i],si_data)
            #     ll.append(ret)
            # return ll
            return [
                # self.child.update(对象,字典) for attrs in validated_data
                self.child.update(instance[i],attrs) for i,attrs in enumerate(validated_data)
            ]
    
    
    
    #如果序列化的是数据库的表,尽量用ModelSerializer
    class BookModelSerializer(serializers.ModelSerializer):
        # 一种方案(只序列化可以,反序列化有问题)
        # publish=serializers.CharField(source='publish.name')
        # 第二种方案,models中写方法
    
        class Meta:
            list_serializer_class=BookListSerializer
            model=models.Book
            # fields='__all__'
            # 用的少
            # depth=0
            sss=serializers.CharField(source='name')
            fields = ('id','name','price','authors','publish','publish_name','author_list','ssss')
    
            extra_kwargs={
                'publish':{'write_only':True},
                'publish_name':{'read_only':True},
                'authors':{'write_only':True},
                'author_list':{'read_only':True}
            }
    ser.py
    from django.urls import path,re_path
    from api import views
    urlpatterns = [
        path('books/', views.BookAPIView.as_view()),
        path('books2/', views.BookView.as_view()), #继承了ListApiView
        re_path('books/(?P<pk>d+)', views.BookAPIView.as_view()),
    ]
    urls.py
    from django.shortcuts import render
    
    # Create your views here.
    
    from rest_framework.response import Response
    
    from api import models
    from  rest_framework.views import APIView
    from rest_framework.generics import GenericAPIView
    from api.ser import BookModelSerializer
    
    class BookAPIView(APIView):
        def get(self,request,*args,**kwargs):
            #查询单个和查询所有,合到一起
            # 查所有
            book_list=models.Book.objects.all().filter(is_delete=False)
            book_list_ser=BookModelSerializer(book_list,many=True)
            return Response(data=book_list_ser.data)
            #查一个
    
        def post(self,request,*args,**kwargs):
            # 具备增单条,和增多条的功能
            if isinstance(request.data,dict):
    
                book_ser=BookModelSerializer(data=request.data)
                book_ser.is_valid(raise_exception=True)
                book_ser.save()
                return Response(data=book_ser.data)
            elif isinstance(request.data,list):
                #现在book_ser是ListSerializer对象
                from rest_framework.serializers import ListSerializer
                book_ser = BookModelSerializer(data=request.data,many=True)  #增多条
                print('--------',type(book_ser))
                book_ser.is_valid(raise_exception=True)
                book_ser.save()
                # 新增---》ListSerializer--》create方法
                # def create(self, validated_data):
                #   self.child是BookModelSerializer对象
                #   print(type(self.child))
                #     return [
                #         self.child.create(attrs) for attrs in validated_data
                #     ]
                return Response(data=book_ser.data)
    
        def put(self,request,*args,**kwargs):
            # 改一个,改多个
            #改一个个
            if kwargs.get('pk',None):
                book=models.Book.objects.filter(pk=kwargs.get('pk')).first()
                book_ser = BookModelSerializer(instance=book,data=request.data,partial=True)  # 增多条
                book_ser.is_valid(raise_exception=True)
                book_ser.save()
                return Response(data=book_ser.data)
            else:
                #改多个,
                # 前端传递数据格式[{id:1,name:xx,price:xx},{id:1,name:xx,price:xx}]
                # 处理传入的数据  对象列表[book1,book2]  修改的数据列表[{name:xx,price:xx},{name:xx,price:xx}]
                book_list=[]
                modify_data=[]
                for item in request.data:
                    #{id:1,name:xx,price:xx}
    
                    pk=item.pop('id')
                    book=models.Book.objects.get(pk=pk)
                    book_list.append(book)
                    modify_data.append(item)
                # 第一种方案,for循环一个一个修改
                #把这个实现
                # for i,si_data in enumerate(modify_data):
                #     book_ser = BookModelSerializer(instance=book_list[i], data=si_data)
                #     book_ser.is_valid(raise_exception=True)
                #     book_ser.save()
                # return Response(data='成功')
                # 第二种方案,重写ListSerializer的update方法
                book_ser = BookModelSerializer(instance=book_list,data=modify_data,many=True)
                book_ser.is_valid(raise_exception=True)
                book_ser.save()  #ListSerializer的update方法,自己写的update方法
                return Response(book_ser.data)
                # request.data
                #
                # book_ser=BookModelSerializer(data=request.data)
    
        def delete(self,request,*args,**kwargs):
            #单个删除和批量删除
            pk=kwargs.get('pk')
            pks=[]
            if pk:
                # 单条删除
                pks.append(pk)
            #不管单条删除还是多条删除,都用多条删除
            #多条删除
            # {'pks':[1,2,3]}
            else:
                pks=request.data.get('pks')
            #把is_delete设置成true
            # ret返回受影响的行数
            ret=models.Book.objects.filter(pk__in=pks,is_delete=False).update(is_delete=True)
            if ret:
                return Response(data={'msg':'删除成功'})
            else:
                return Response(data={'msg': '没有要删除的数据'})
    
    
    
    
    
    
    
    # 查所有,才需要分页
    from rest_framework.generics import ListAPIView
    # 内置三种分页方式
    from  rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
    '''
    PageNumberPagination
        page_size:每页显示的条数
    '''
    class MyPageNumberPagination(PageNumberPagination):
        #http://127.0.0.1:8000/api/books2/?aaa=1&size=6
        page_size=3  #每页条数
        page_query_param='aaa' #查询第几页的key
        page_size_query_param='size' # 每一页显示的条数
        max_page_size=5    # 每页最大显示条数
    
    
    # class MyLimitOffsetPagination(LimitOffsetPagination):
    #     default_limit = 3   # 每页条数
    #     limit_query_param = 'limit' # 往后拿几条
    #     offset_query_param = 'offset' # 标杆
    #     max_limit = 5   # 每页最大几条
    
    class MyCursorPagination(CursorPagination):
        cursor_query_param = 'cursor'  # 每一页查询的key
        page_size = 2   #每页显示的条数
        ordering = '-id'  #排序字段
    # class BookView(ListAPIView):
    #     # queryset = models.Book.objects.all().filter(is_delete=False)
    #     queryset = models.Book.objects.all()
    #     serializer_class = BookModelSerializer
    #     #配置分页
    #     pagination_class = MyCursorPagination
    
    # 如果使用APIView分页
    from utils.throttling import MyThrottle
    class BookView(APIView):
        # throttle_classes = [MyThrottle,]
        def get(self,request,*args,**kwargs):
            book_list=models.Book.objects.all()
            # 实例化得到一个分页器对象
            page_cursor=MyPageNumberPagination()
    
            book_list=page_cursor.paginate_queryset(book_list,request,view=self)
            next_url =page_cursor.get_next_link()
            pr_url=page_cursor.get_previous_link()
            # print(next_url)
            # print(pr_url)
            book_ser=BookModelSerializer(book_list,many=True)
            return Response(data=book_ser.data)
    views.py
    from rest_framework.throttling import ScopedRateThrottle,SimpleRateThrottle
    
    
    #继承SimpleRateThrottle
    class MyThrottle(SimpleRateThrottle):
        scope='luffy'
        def get_cache_key(self, request, view):
            print(request.META.get('REMOTE_ADDR'))
            return request.META.get('REMOTE_ADDR')
    throttling.py
    REST_FRAMEWORK={
        'DEFAULT_THROTTLE_CLASSES': (
            'utils.throttling.MyThrottle',
        ),
        'DEFAULT_THROTTLE_RATES': {
            'luffy': '3/m'  # key要跟类中的scop对应
        },
        'PAGE_SIZE': 2,
    }
    settings.py
    from django.db import models
    
    
    
    
    from django.contrib.auth.models import AbstractUser
    class BaseModel(models.Model):
        is_delete=models.BooleanField(default=False)
        # auto_now_add=True 只要记录创建,不需要手动插入时间,自动把当前时间插入
        create_time=models.DateTimeField(auto_now_add=True)
        # auto_now=True,只要更新,就会把当前时间插入
        last_update_time=models.DateTimeField(auto_now=True)
        # import datetime
        # create_time=models.DateTimeField(default=datetime.datetime.now)
        class Meta:
            # 单个字段,有索引,有唯一
            # 多个字段,有联合索引,联合唯一
            abstract=True  # 抽象表,不再数据库建立出表
    
    
    
    
    class Book(BaseModel):
        id=models.AutoField(primary_key=True)
        # verbose_name admin中显示中文
        name=models.CharField(max_length=32,verbose_name='书名',help_text='这里填书名')
        price=models.DecimalField(max_digits=5,decimal_places=2)
        # 一对多的关系一旦确立,关联字段写在多的一方
        #to_field 默认不写,关联到Publish主键
        #db_constraint=False  逻辑上的关联,实质上没有外键练习,增删不会受外键影响,但是orm查询不影响
        publish=models.ForeignKey(to='Publish',on_delete=models.DO_NOTHING,db_constraint=False)
    
        # 多对多,跟作者,关联字段写在 查询次数多的一方
    
        # 什么时候用自动,什么时候用手动?第三张表只有关联字段,用自动    第三张表有扩展字段,需要手动写
        # 不能写on_delete
        authors=models.ManyToManyField(to='Author',db_constraint=False)
        class Meta:
            verbose_name_plural='书表'  # admin中表名的显示
    
        def __str__(self):
            return self.name
    
        @property
        def publish_name(self):
            return self.publish.name
        # def author_list(self):
        def author_list(self):
            author_list=self.authors.all()
            # ll=[]
            # for author in author_list:
            #     ll.append({'name':author.name,'sex':author.get_sex_display()})
            # return ll
            return [ {'name':author.name,'sex':author.get_sex_display()}for author in author_list]
    
    class Publish(BaseModel):
        name = models.CharField(max_length=32)
        addr=models.CharField(max_length=32)
        def __str__(self):
            return self.name
    
    
    class Author(BaseModel):
        name=models.CharField(max_length=32)
        sex=models.IntegerField(choices=((1,''),(2,'')))
        # 一对一关系,写在查询频率高的一方
        #OneToOneField本质就是ForeignKey+unique,自己手写也可以
        authordetail=models.OneToOneField(to='AuthorDetail',db_constraint=False,on_delete=models.CASCADE)
    
    class AuthorDetail(BaseModel):
        mobile=models.CharField(max_length=11)
    
    # 二、表断关联
    # 1、表之间没有外键关联,但是有外键逻辑关联(有充当外键的字段)
    # 2、断关联后不会影响数据库查询效率,但是会极大提高数据库增删改效率(不影响增删改查操作)
    # 3、断关联一定要通过逻辑保证表之间数据的安全,不要出现脏数据,代码控制
    # 4、断关联
    # 5、级联关系
    #       作者没了,详情也没:on_delete=models.CASCADE
    #       出版社没了,书还是那个出版社出版:on_delete=models.DO_NOTHING
    #       部门没了,员工没有部门(空不能):null=True, on_delete=models.SET_NULL
    #       部门没了,员工进入默认部门(默认值):default=0, on_delete=models.SET_DEFAULT
    models.py
    from django.contrib import admin
    
    # Register your models here.
    
    
    from api import models
    
    
    admin.site.register(models.Book)
    admin.site.register(models.Publish)
    admin.site.register(models.Author)
    admin.site.register(models.AuthorDetail)
    admin.py

    drf_token

    # 配置头像相关
    MEDIA_URL='/media/'
    MEDIA_ROOT=os.path.join(BASE_DIR,'media')
    
    #一定不要忘了
    AUTH_USER_MODEL='api.user'
    
    
    REST_FRAMEWORK={
        'DEFAULT_AUTHENTICATION_CLASSES':['rest_framework_jwt.authentication.JSONWebTokenAuthentication']
    }
    
    JWT_AUTH={
        'JWT_AUTH_HEADER_PREFIX': '',
    }
    settings.py
    from django.contrib import admin
    from django.urls import path
    
    
    from rest_framework_jwt.views import ObtainJSONWebToken,VerifyJSONWebToken,RefreshJSONWebToken,obtain_jwt_token
    # 基类:JSONWebTokenAPIView继承了APIView,
    # ObtainJSONWebToken,VerifyJSONWebToken,RefreshJSONWebToken都继承了JSONWebTokenAPIView
    '''
    obtain_jwt_token = ObtainJSONWebToken.as_view()
    refresh_jwt_token = RefreshJSONWebToken.as_view()
    verify_jwt_token = VerifyJSONWebToken.as_view()
    '''
    from api import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        # path('login/', ObtainJSONWebToken.as_view()),
        path('login/', obtain_jwt_token),
        path('books/', views.BookView.as_view()),
    ]
    urls.py
    from rest_framework_jwt.authentication import BaseAuthentication,BaseJSONWebTokenAuthentication
    from rest_framework.exceptions import AuthenticationFailed
    from rest_framework_jwt.authentication import jwt_decode_handler
    from rest_framework_jwt.authentication import get_authorization_header,jwt_get_username_from_payload
    from rest_framework import exceptions
    class MyToken(BaseJSONWebTokenAuthentication):
        def authenticate(self, request):
            jwt_value=str(request.META.get('HTTP_AUTHORIZATION'))
            # 认证
            try:
                payload = jwt_decode_handler(jwt_value)
    
            except Exception:
                raise exceptions.AuthenticationFailed("认证失败")
            user=self.authenticate_credentials(payload)
            return user,None
    auth.py
    from django.db import models
    
    from django.contrib.auth.models import AbstractUser
    
    
    class User(AbstractUser):
        phone=models.CharField(max_length=11)
        icon=models.ImageField(upload_to='icon')  # ImageField依赖于pillow模块
    models.py
    from django.shortcuts import render
    
    
    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    from rest_framework_jwt.authentication import JSONWebTokenAuthentication
    from api.auth import MyToken
    class BookView(APIView):
        authentication_classes = [MyToken,]
        def get(self,request):
            print(request.user.email)
            return Response('ok')
    views.py

    drf_...

    # base64编码和解码
    #md5固定长度,不可反解
    #base63 变长,可反解
    
    #编码(字符串,json格式字符串)
    import base64
    import json
    dic={'name':'lqz','age':18,'sex':''}
    dic_str=json.dumps(dic)
    
    ret=base64.b64encode(dic_str.encode('utf-8'))
    print(ret)
    
    # 解码
    # ret是带解码的串
    ret2=base64.b64decode(ret)
    print(ret2)
    base64
    from django.contrib import admin
    from django.urls import path,include,re_path
    from django.views.static import serve  # django内置给你的一个视图函数
    from django.conf import settings  # 以后取配置文件,都用这个
    # from drf_day12 import settings
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('api/',include('api.urls')),  # 路由分发
        path('app02/',include('app02.urls')),
        # 开放media文件
        re_path('media/(?P<path>.*)', serve,{'document_root':settings.MEDIA_ROOT}),
    
    ]
    urls.py
    STATIC_URL = '/static/'
    
    MEDIA_URL='/media/'
    MEDIA_ROOT=os.path.join(BASE_DIR,'media')   #真正的文件夹路径
    
    #指定使用的auth表是自己定义的
    
    AUTH_USER_MODEL='api.user'   #app名.表名
    
    
    
    # jwt的配置
    import datetime
    JWT_AUTH={
        'JWT_RESPONSE_PAYLOAD_HANDLER':'app02.utils.my_jwt_response_payload_handler',
        'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7), # 过期时间,手动配置
    }
    
    
    CACHES = {
     'default': {
      'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #指定缓存使用的引擎
      'LOCATION': 'D:django_cache',        #指定缓存的路径
      'TIMEOUT':300,              #缓存超时时间(默认为300秒,None表示永不过期)
      'OPTIONS':{
       'MAX_ENTRIES': 300,            # 最大缓存记录的数量(默认300)
       'CULL_FREQUENCY': 3,           # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
      }
     }
    }
    settings.py
    from django.db import models
    
    # Create your models here.
    from django.contrib.auth.models import AbstractUser
    
    class User(AbstractUser):
        mobile=models.CharField(max_length=32,unique=True)  #唯一
        icon=models.ImageField(upload_to='icon',default='icon/default.png')  #需要配media文件夹,上传的文件就会放到media文件夹下的icon
    
    
    class Book(models.Model):
        name = models.CharField(max_length=64)
    
        def __str__(self):
            return self.name
    
    
    class Car(models.Model):
        name = models.CharField(max_length=64)
    
        def __str__(self):
            return self.name
    models.py
    from rest_framework import serializers
    from api import models
    from rest_framework.exceptions import ValidationError
    class UserModelSerializer(serializers.ModelSerializer):
        re_password=serializers.CharField(max_length=16,min_length=4,required=True,write_only=True) # 因为re_password在表中没有,需要在这定义
        class Meta:
            model=models.User
            fields=['username','password','mobile','re_password','icon']
            extra_kwargs={
                'username':{'max_length':16},
                'password':{'write_only':True}
            }
        # 局部钩子
        def validate_mobile(self,data):
            if not len(data)==11:
                raise ValidationError('手机号不合法')
            return data
        # 全局钩子
        def validate(self, attrs):
            if not attrs.get('password')==attrs.get('re_password'):
                raise ValidationError('两次密码不一致')
            attrs.pop('re_password')# 剔除该字段,因为数据库没有这个字段
            return attrs
        def create(self, validated_data):
            # attrs.pop('re_password') 如果上面没有剔除,在这也可以
            # models.User.objects.create(**validated_data) 这个密码不会加密
            user=models.User.objects.create_user(**validated_data)
            return user
    
    
    class UserReadOnlyModelSerializer(serializers.ModelSerializer):
       class Meta:
            model=models.User
            fields=['username','icon']
    
    class UserImageModelSerializer(serializers.ModelSerializer):
       class Meta:
            model=models.User
            fields=['icon']
    ser.py
    from django.shortcuts import render
    
    # Create your views here.
    from rest_framework.viewsets import GenericViewSet
    #ViewSetMixin:重写了as_view,路由配置变样了, generics.GenericAPIView:只需要配俩东西
    from rest_framework.mixins import CreateModelMixin,RetrieveModelMixin,UpdateModelMixin
    
    from api import ser
    from api import models
    class RegisterView(GenericViewSet,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin):
        queryset = models.User.objects.all()
        serializer_class =ser.UserModelSerializer
    
        # 假设get请求和post请求,用的序列化类不一样,如何处理?
        # 重写getget_serializer_class,返回啥,用的序列号类就是啥
        # 注册,用的序列化类是UserModelSerializer,查询一个用的序列化类是UserReadOnlyModelSerializer
        def get_serializer_class(self):
            print(self.action)  # create,retrieve
            if self.action=='create':
                return ser.UserModelSerializer
            elif self.action=='retrieve':
                return ser.UserReadOnlyModelSerializer
            elif self.action=='update':
                return  ser.UserImageModelSerializer
    views.py
    from rest_framework import serializers
    from api import models
    import re
    from rest_framework.exceptions import ValidationError
    
    from rest_framework_jwt.utils import jwt_encode_handler,jwt_payload_handler
    class LoginModelSerializer(serializers.ModelSerializer):
        username=serializers.CharField()  # 重新覆盖username字段,数据中它是unique,post,认为你保存数据,自己有校验没过
        class Meta:
            model=models.User
            fields=['username','password']
    
        def validate(self, attrs):
    
            print(self.context)
    
            # 在这写逻辑
            username=attrs.get('username') # 用户名有三种方式
            password=attrs.get('password')
            # 通过判断,username数据不同,查询字段不一样
            # 正则匹配,如果是手机号
            if re.match('^1[3-9][0-9]{9}$',username):
                user=models.User.objects.filter(mobile=username).first()
            elif re.match('^.+@.+$',username):# 邮箱
                user=models.User.objects.filter(email=username).first()
            else:
                user=models.User.objects.filter(username=username).first()
            if user: # 存在用户
                # 校验密码,因为是密文,要用check_password
                if user.check_password(password):
                    # 签发token
                    payload = jwt_payload_handler(user)  # 把user传入,得到payload
                    token = jwt_encode_handler(payload)  # 把payload传入,得到token
                    self.context['token']=token
                    self.context['username']=user.username
                    return attrs
                else:
                    raise ValidationError('密码错误')
            else:
                raise ValidationError('用户不存在')
    
    
    
    '''
    jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
    jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
    
    payload = jwt_payload_handler(user) # 把user传入,得到payload
    token = jwt_encode_handler(payload) # 把payload传入,得到token
    
    '''
    ser.py
    from django.contrib import admin
    from django.urls import path,include,re_path
    from django.views.static import serve  # django内置给你的一个视图函数
    from django.conf import settings  # 以后取配置文件,都用这个
    # from drf_day12 import settings
    from rest_framework_jwt.views import obtain_jwt_token
    from app02 import views
    urlpatterns = [
        path('login/', obtain_jwt_token),
        path('order/', views.OrderAPIView.as_view()),
        path('userinfo/', views.UserInfoAPIView.as_view()),
        path('goods/', views.GoodsInfoAPIView.as_view()),
        path('login2/', views.Login2View.as_view({'post':'login'})),
    
        # 缓存
        path('test/', views.test_cache),
        path('test2/', views.test_cache2)
    
    ]
    urls.py
    def my_jwt_response_payload_handler(token, user=None, request=None): # 返回什么,前端就能看到什么样子
        return {
            'token': token,
            'msg':'登录成功',
            'status':100,
            'username':user.username
    
        }
    from rest_framework.authentication import BaseAuthentication  # 基于它
    from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication # 基于它
    from rest_framework.exceptions import AuthenticationFailed
    # from rest_framework_jwt.authentication import jwt_decode_handler
    from rest_framework_jwt.utils import jwt_decode_handler # 跟上面是一个
    import jwt
    
    from api import models
    # class MyJwtAuthentication(BaseAuthentication):
    #     def authenticate(self, request):
    #         jwt_value=request.META.get('HTTP_AUTHORIZATION')
    #         if jwt_value:
    #             try:
    #             #jwt提供了通过三段token,取出payload的方法,并且有校验功能
    #                 payload=jwt_decode_handler(jwt_value)
    #             except jwt.ExpiredSignature:
    #                 raise AuthenticationFailed('签名过期')
    #             except jwt.InvalidTokenError:
    #                 raise AuthenticationFailed('用户非法')
    #             except Exception as e:
    #                 # 所有异常都会走到这
    #                 raise AuthenticationFailed(str(e))
    #             # 因为payload就是用户信息的字典
    #             print(payload)
    #             # return payload, jwt_value
    #             # 需要得到user对象,
    #             # 第一种,去数据库查
    #             # user=models.User.objects.get(pk=payload.get('user_id'))
    #             # 第二种不查库
    #             user=models.User(id=payload.get('user_id'),username=payload.get('username'))
    #             return user,jwt_value
    #         # 没有值,直接抛异常
    #         raise AuthenticationFailed('您没有携带认证信息')
    
    
    class MyJwtAuthentication(BaseJSONWebTokenAuthentication):
        def authenticate(self, request):
            jwt_value=request.META.get('HTTP_AUTHORIZATION')
            if jwt_value:
                try:
                #jwt提供了通过三段token,取出payload的方法,并且有校验功能
                    payload=jwt_decode_handler(jwt_value)
                except jwt.ExpiredSignature:
                    raise AuthenticationFailed('签名过期')
                except jwt.InvalidTokenError:
                    raise AuthenticationFailed('用户非法')
                except Exception as e:
                    # 所有异常都会走到这
                    raise AuthenticationFailed(str(e))
                user=self.authenticate_credentials(payload)
                return user,jwt_value
            # 没有值,直接抛异常
            raise AuthenticationFailed('您没有携带认证信息')
    utils.py
    from django.shortcuts import render
    
    # Create your views here.
    from rest_framework.views import APIView
    
    from rest_framework.response import Response
    # 使用jwt提供的认证类,局部使用
    from rest_framework_jwt.authentication import JSONWebTokenAuthentication
    
    # 内置权限类
    
    # 可以通过认证类:JSONWebTokenAuthentication和权限类IsAuthenticated,来控制用户登录以后才能访问某些接口
    # 如果用户不登录就可以访问,只需要把权限类IsAuthenticated去掉就可以了
    from rest_framework.permissions import IsAuthenticated
    class OrderAPIView(APIView):
        authentication_classes = [JSONWebTokenAuthentication,]
        # 权限控制
        permission_classes = [IsAuthenticated,]
        def get(self,request,*args,**kwargs):
            return Response('这是订单信息')
    
    
    class UserInfoAPIView(APIView):
        authentication_classes = [JSONWebTokenAuthentication,]
        # 权限控制
        # permission_classes = [IsAuthenticated,]
        def get(self,request,*args,**kwargs):
            return Response('UserInfoAPIView')
    
    
    
    
    #
    from rest_framework_jwt.utils import jwt_response_payload_handler
    from app02.utils import MyJwtAuthentication
    class GoodsInfoAPIView(APIView):
        authentication_classes = [MyJwtAuthentication,]
    
        def get(self,request,*args,**kwargs):
            print(request.user)
            return Response('商品信息')
    
    
    # 手动签发token,完成多方式登录
    from rest_framework.views import APIView
    from rest_framework.viewsets import ViewSetMixin, ViewSet
    
    from app02 import ser
    # class Login2View(ViewSetMixin,APIView):
    class Login2View(ViewSet):  # 跟上面完全一样
        # 这是登录接口
        # def post(self):  # 不写post了,直接写login?
        #     pass
    
        def login(self, request, *args, **kwargs):
    
            # 1 需要 有个序列化的类
            login_ser = ser.LoginModelSerializer(data=request.data,context={'request':request})
            # 2 生成序列化类对象
            # 3 调用序列号对象的is_validad
            login_ser.is_valid(raise_exception=True)
            token=login_ser.context.get('token')
            # 4 return
            return Response({'status':100,'msg':'登录成功','token':token,'username':login_ser.context.get('username')})
    
    
        # 逻辑在视图类中写
    
        # def login(self, request, *args, **kwargs):
        #     username=request.data.get('username') # 用户名有三种方式
        #     password=request.data.get('password')
        #     import re
        #     from api import models
        #     from rest_framework_jwt.utils import jwt_encode_handler, jwt_payload_handler
        #     # 通过判断,username数据不同,查询字段不一样
        #     # 正则匹配,如果是手机号
        #     if re.match('^1[3-9][0-9]{9}$',username):
        #         user=models.User.objects.filter(mobile=username).first()
        #     elif re.match('^.+@.+$',username):# 邮箱
        #         user=models.User.objects.filter(email=username).first()
        #     else:
        #         user=models.User.objects.filter(username=username).first()
        #     if user: # 存在用户
        #         # 校验密码,因为是密文,要用check_password
        #         if user.check_password(password):
        #             # 签发token
        #             payload = jwt_payload_handler(user)  # 把user传入,得到payload
        #             token = jwt_encode_handler(payload)  # 把payload传入,得到token
        #            return Response()
    
    
    # 单页面缓存
    from django.views.decorators.cache import cache_page
    
    
    
    class Person:
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
    
    from django.core.cache import cache
    # @cache_page(5)  # 缓存5s钟
    def test_cache(request):
        p=Person('lqz',18)
        cache.set('name',p)
        import time
        ctime=time.time()
        return render(request,'index.html',context={'ctime':ctime})
    
    
    def test_cache2(request):
    
        p=cache.get('name')
        print(type(p))
        print(p.name)
        import time
        ctime = time.time()
        return render(request, 'index.html', context={'ctime': ctime})
    views.py
  • 相关阅读:
    JavaScript手把手教你写出令人窒息的烂代码
    查询数据库表名,数据表信息,MySQL Key值(PRI, UNI, MUL)的含义
    【转载】 世界读书日:来自李开复的六个读书建议
    安装python库roboschool运行报错:ImportError: libpcre16.so.3: cannot open shared object file——解决方法
    Python 二次开发 AutoCAD 简介
    MATLAB元胞数组删除一个元素
    英语单词积累
    一战后德国要支付1320亿金马克的赔款,都按期足额付完了吗
    cad无级缩放
    [转]mysql导入数据load data infile用法
  • 原文地址:https://www.cnblogs.com/bubu99/p/13763275.html
Copyright © 2020-2023  润新知