当你发现自己的才华撑不起野心时,就请安静下来学习吧。

Personal site

↑点击传送

Book多增多删接口、分页器、IP限制

Book多增多删接口、分页器、IP限制

多增多删接口

#views.py
    from rest_framework.views import APIView

    from app01.models import Book
    from app01.ser import BookModelSerializer
    from app01.utils.response import APIResponse


    class BookAPIView(APIView):
        #查单个、查所有
        def get(self,request,*args,**kwargs):
            pk = kwargs.get('pk')
            if pk:
                print('少')
                book = Book.objects.filter(pk=pk,is_delete=False).first()
                book_ser = BookModelSerializer(book)
                return APIResponse(data=book_ser.data)
            else:
                print('多')
                book_list = Book.objects.filter(is_delete=False).all()
                book_list_ser = BookModelSerializer(book_list,many=True)
                return APIResponse(data=book_list_ser.data)
        def post(self,request,*args,**kwargs):
            #规定前端格式、字典是单个数据,列表是多个数据
            #isinstance判断request.data是不是字典,是就单增
            if isinstance(request.data,dict):
                print('少')
                book_ser = BookModelSerializer(data=request.data)
                #数据效验失败抛出异常,不需要判断是否合法了
                book_ser.is_valid(raise_exception=True)
                book_ser.save()
                return APIResponse(data=book_ser.data)
            # isinstance判断request.data是不是列表,是就群增
            elif isinstance(request.data,list):
                print('多')
                #此时需要用BookListSerializer来群增
                book_ser = BookModelSerializer(data=request.data,many=True)
                book_ser.is_valid(raise_exception=True)
                book_ser.save()
                return APIResponse(data=book_ser.data)
        def delete(self,request,*args,**kwargs):
            pk = kwargs.get('pk')
            pks = []
            if pk:
                pks.append(pk)
            else:
                pks = request.data.get('pks')
            print(pks)
            #pk__in就是在pks一个一个循环
            ret = Book.objects.filter(pk__in=pks,is_delete=False).update(is_delete=True)
            if ret:
                print(ret)
                return APIResponse(msg='删除成功%s条数据'%(ret))
            else:
                return APIResponse(msg='没有需要删除的数据')
        def put(self,requesst,*args,**kwargs):
            if kwargs.get('pk'):
                #改单个
                print('少')
                book = Book.objects.filter(pk=kwargs.get('pk')).first()
                #partial=True表示改局部的,相当于其他字段等于required=False
                book_ser = BookModelSerializer(instance=book,data=requesst.data,partial=True)
                # raise_exception=True报错建议自定义异常处理,会被捕获
                book_ser.is_valid(raise_exception=True)
                book_ser.save()
                return APIResponse(data=book_ser.data)
            else:
                print('多')
                #改多个,要求格式列表套字典[{id:1,name:xx,price:xx},{id:1,name:xx,price:xx}]
                book_list = []
                #modify_data修改的数据
                modify_data = []
                for item in requesst.data:
                    print(item)
                    pk = item.pop('id')
                    book = Book.objects.get(pk=pk)
                    book_list.append(book)
                    modify_data.append(item)
                    # print(modify_data)
                    #第一方案,for循环一个个改
                #     for i,put_data in enumerate(modify_data):
                #         book_ser = BookModelSerializer(instance=book_list[i],data=put_data)
                #         book_ser.is_valid(raise_exception=True)
                #         book_ser.save()
                # return APIResponse(data=book_ser.data)
                    #第二种方案,重写ListSerializer的update方法
                print(book_list,modify_data)
                book_ser = BookModelSerializer(instance=book_list,data=modify_data,many=True,partial=True)
                book_ser.is_valid(raise_exception=True)
                book_ser.save()
                return APIResponse({'msg':'修改成功'})
#modles.py
    from django.db import models


    class BaseModel(models.Model):
        is_delete = models.BooleanField(default=False)
        create_time = models.DateTimeField(auto_now_add=True)
        last_update_time = models.DateTimeField(auto_now=True)

        class Meta:
            abstract = True#抽象表,不在数据库创建


    class Book(BaseModel):
        name = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=5,decimal_places=2)
        authors = models.ManyToManyField(to='Author',db_constraint=False)
        publishs = models.ManyToManyField(to='Publish',db_constraint=False)
        def __str__(self):
            return self.name

        @property
        def author_list(self):
            author_list2 = self.authors.all()
            return [{'name':author.name,'sex':author.get_sex_display()}for author in author_list2]

        @property
        def publish_list(self):
            publish_list2 = self.publishs.all()
            return [{'name':pubisj.name,'addr':pubisj.addr}for pubisj in publish_list2]


    class Author(BaseModel):
        name = models.CharField(max_length=32)
        sex = models.IntegerField(choices=((1,'男'),(2,'女')))
        authordetail = models.OneToOneField(to='AuthorDetail',db_constraint=False,on_delete=models.CASCADE)


    class AuthorDetail(BaseModel):
        age = models.IntegerField()
        mobile = models.CharField(max_length=11)


    class Publish(BaseModel):
        name = models.CharField(max_length=32)
        addr = models.CharField(max_length=32)

        def __str__(self):
            return self.name

#ser.py
    from rest_framework import serializers

    from app01.models import Book


    class BookListSerializer(serializers.ListSerializer):
        def update(self, instance, validated_data):
            print(instance,validated_data)
            return [self.child.update(instance[i],attrs) for i, attrs in enumerate(validated_data)]



    class BookModelSerializer(serializers.ModelSerializer):
        name = serializers.CharField()
        class Meta:
            list_serializer_class = BookListSerializer
            model=Book
            fields = ('id','name','price','authors','author_list','publishs','publish_list')
            extra_kwargs = {
                # 'id':{'read_only':True},
                'author_list':{'read_only':True},
                'authors':{'write_only':True},
                'publishs':{'write_only':True},
                'publish_list':{'read_only':True}
            }

admin.py注册下,方便admin页面添加数据

from app01 import models

admin.site.register(models.Book)
admin.site.register(models.Author)
admin.site.register(models.AuthorDetail)
admin.site.register(models.Publish)

自定义的reponse对象

from rest_framework.response import Response


class APIResponse(Response):
    def __init__(self, code=100, msg='成功', data=None, status=None, headerrs=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=headerrs)

只有上下页的分页器

#查所有才需要分页
#基于APIView分页
from rest_framework.views import APIView

from app01.utils.throttling import MyCursorPagination
from app01.models import Book
from app01.ser import BookModelSerializer
from app01.utils.response import APIResponse

class BookTestAPIview(APIView):
    def get(self,request,*args,**kwargs):
        book_list = Book.objects.all()
        #实例化得到分页器对象
        page_cursor = MyCursorPagination()
        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,pr_url)
        book_ser = BookModelSerializer(book_list,many=True)
        return APIResponse(data=book_ser.data)

throttling.py

from rest_framework.pagination import CursorPagination


class MyCursorPagination(CursorPagination):
    cursor_query_param = 'cursor'  # 每一页查询的key
    page_size = 2   #每页显示的条数
    ordering = 'id'  #排序字段

IP进行频率限制

#写一个类,继承SimpleRateThrottle,重写get_cache_key 
#ipthrottling.py
    #IP频率限制
    from rest_framework.throttling import SimpleRateThrottle
    class MyThrottle(SimpleRateThrottle):
        scope = 'luffy'
        def get_cache_key(self, request, view):
            return request.META.get('REMOTE_ADDR')
#全局配置
	#settins.py
        REST_FRAMEWORK={
            'DEFAULT_THROTTLE_CLASSES': (
                'app01.utils.ipthrotting.MyThrottle',
            ),
            'DEFAULT_THROTTLE_RATES': {
                'luffy': '3/m'  # key要跟类中的scop对应
            },
        }
    #views.py
        from rest_framework.views import APIView

        from app01.utils.response import APIResponse
        class TestAPIView(APIView):
            def get(self,request,*args,**kwargs):
                return APIResponse()#这是自定义的Response对象,可以用from rest_framework.response import Response的
#局部使用
	#settings.py
        REST_FRAMEWORK={
            'DEFAULT_THROTTLE_RATES': {
                'luffy': '3/m'  # key要跟类中的scop对应},}
    #views.py
        from rest_framework.views import APIView
        from app01.utils.response import APIResponse
        from app01.utils.ipthrotting import MyThrottle
        class TestAPIView(APIView):
            throttle_classes = [MyThrottle]
            def get(self,request,*args,**kwargs):
                return APIResponse()#这是自定义的Response对象,可以用from rest_framework.response import Response的
posted @ 2020-07-21 16:26  Joab-0429  阅读(158)  评论(0编辑  收藏  举报