zoukankan      html  css  js  c++  java
  • 多对多表的增删改查与drf的分页

    类的约束

    继承 必须继续 定义 不然报错

    # 约束子类中必须实现f1 class Base(object):
    def f1(self):
    	raise NotImplementedError('必须要定义此规则')
    
    class Foo(Base):
    
        def f1(self):
        print(123)
    
    obj = Foo() 
    obj.f1()
    

    面向对象的继承

    class Base(object): 
    	def f1(self):
    		print('base.f1') 
    		self.f2()
    	def f2(self):
    		print('base.f2')
    class Foo(Base):
    	def f2(self):
    	print('foo.f2')
    
    obj = Foo() 
    obj.f1()
    
    class Base(object): 
    	x1 = 123
    
    def f1(self):
    	print(self.x1)
    
    class Foo(Base): 
    	x1 = 456
    
    obj = Foo() 
    obj.f1()
    
    class APIView(object): 
    	version_class = 123
        
        def get_version(self): 
            print(self.version_class)
    
    class UserView(APIView): 
    	version_class = 666
    
    obj = UserView() 
    obj.get_version()
    
    class APIView(object): 
        version_class = 123
    
        def dispatch(self,method):
            self.initial() 
            getattr(self,method)()#反射
    
        def initial(self):
            print(self.version_class)
    
    class UserView(APIView): 
        version_class = 666
    
        def get(self): 
            print('userview.get')
    
    obj = UserView() 
    obj.dispatch('get')
    
    结果
    print(self.version_class)
    print('userview.get')
    
    class URLPathVersion(object):
    
    	def determin_version(self): 
            return 'v1'
    class APIView(object): 
        version_class = None
    
        def dispatch(self,method): 
            version = self.initial() 
            print(version) 
            getattr(self,method)()
    
        def initial(self): 
            self.process_version()
    
        def process_version():
            obj = self.version_class() 
            return obj.determine_version()
    
    class UserView(APIView): 
        version_class = URLPathVersion
        
    	def get(self): 
        	print('userview.get')
    
    obj = UserView() 
    obj.dispatch('get')
    

    处理 多对多实列

    查询 单条或多条

    modul

    from django.db import models
    
    class Category(models.Model):
        """
        文章分类
        """
        name = models.CharField(verbose_name='分类',max_length=32)
    
    
    class Article(models.Model):
        """
        文章表
        """
        status_choices = (
            (1,'发布'),
            (2,'删除'),
        )
        status = models.IntegerField(verbose_name='状态',choices=status_choices,default=1)
        title = models.CharField(verbose_name='标题',max_length=32)
        summary = models.CharField(verbose_name='简介',max_length=255)
        content = models.TextField(verbose_name='文章内容')
        category = models.ForeignKey(verbose_name='分类',to='Category')
    
        tag = models.ManyToManyField(verbose_name='标签',to='Tag',null=True,blank=True)
    
    class Tag(models.Model):
        """标签"""
        title = models.CharField(verbose_name='标签',max_length=32)
    
    
    

    url

    from django.conf.urls import url
    from django.contrib import admin
    from api import views
    urlpatterns = [
        url(r'^new/article/$', views.NewArticleView.as_view()),
        url(r'^new/article/(?P<pk>d+)/$', views.NewArticleView.as_view()),
    
    ]
    

    约束 展示

    class NewArticleSerializer(serializers.ModelSerializer):
        tag_info = serializers.SerializerMethodField()
        
        class Meta:
            model = models.Article
            # fields = '__all__' #会自动展示
            fields = ['title','summary','tag_info']#自定义显示 必须自己加 tag_info
    
        def get_tag_info(self,obj):#展示的第3种方法 obj对象
            return [row for row in obj.tag.all().values('id','title')]#字典加列表的形式
    
        
    obj.字段.all().values('要显示的字段1','要显示的字段2')
    

    view

    class NewArticleView(APIView):
    
        def get(self,request,*args,**kwargs):
            pk = kwargs.get('pk')
            if not pk:
                queryset = models.Article.objects.all()
                ser = serializer.NewArticleSerializer(instance=queryset,many=True)
                return Response(ser.data)
            
            article_object = models.Article.objects.filter(id=pk).first()
            ser = serializer.NewArticleSerializer(instance=article_object, many=False)
            return Response(ser.data)
    
        def post(self,request,*args,**kwargs):
            ser = serializer.FormNewArticleSerializer(data=request.data)
            if ser.is_valid():
                ser.save()
                return Response(ser.data)
            return Response(ser.errors)
    
        def put(self, request, *args, **kwargs):
            """全部更新"""
            pk = kwargs.get('pk')
            article_object = models.Article.objects.filter(id=pk).first()
            ser = serializer.FormNewArticleSerializer(instance=article_object, data=request.data)
            if ser.is_valid():
                ser.save()
                return Response(ser.data)
            return Response(ser.errors)
    
        def patch(self,request,*args,**kwargs):
            """局部"""
            pk = kwargs.get('pk')
            article_object = models.Article.objects.filter(id=pk).first()
            ser = serializer.FormNewArticleSerializer(instance=article_object, data=request.data,partial=True)
            if ser.is_valid():
                ser.save()
                return Response(ser.data)
            return Response(ser.errors)
    
        def delete(self,request,*args,**kwargs):
            pk = kwargs.get('pk')
            models.Article.objects.filter(id=pk).delete()
            return Response('删除成功')
    
    

    增加 编辑 更新

    要注意的是 约束 可以用不一样的 为了避免展示与增加不一样

    约束

    class FormNewArticleSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Article
            fields = '__all__'
            
    增加 编辑必须为 __all__
    

    view

    class NewArticleView(APIView):
    
    
        def post(self,request,*args,**kwargs):
            """增加"""
            ser = serializer.FormNewArticleSerializer(data=request.data)
            if ser.is_valid():
                ser.save()
                return Response(ser.data)
            return Response(ser.errors)
    
        def put(self, request, *args, **kwargs):
            """全部更新"""
            pk = kwargs.get('pk')
            article_object = models.Article.objects.filter(id=pk).first()
            ser = serializer.FormNewArticleSerializer(instance=article_object, data=request.data)
            if ser.is_valid():
                ser.save()
                return Response(ser.data)
            return Response(ser.errors)
    
        def patch(self,request,*args,**kwargs):
            """局部"""
            pk = kwargs.get('pk')
            article_object = models.Article.objects.filter(id=pk).first()
            ser = serializer.FormNewArticleSerializer(instance=article_object, data=request.data,partial=True)
            if ser.is_valid():
                ser.save()
                return Response(ser.data)
            return Response(ser.errors)
    
        def delete(self,request,*args,**kwargs):
            pk = kwargs.get('pk')
            models.Article.objects.filter(id=pk).delete()
            return Response('删除成功')
    
    

    总结

    根据业务需求不同 所以 serializers可以写多个 来应对
    

    分页器

    为什么要使用分页

    其实这个不说大家都知道,大家写项目的时候也是一定会用的,

    我们数据库有几千万条数据,这些数据需要展示,我们不可能直接从数据库把数据全部读取出来,

    这样会给内存造成特别大的压力,有可能还会内存溢出,所以我们希望一点一点的取,

    那展示的时候也是一样的,总是要进行分页显示,我们之前自己都写过分页。

    那么大家想一个问题,在数据量特别大的时候,我们的分页会越往后读取速度越慢,

    当有一千万条数据,我要看最后一页的内容的时候,怎么能让我的查询速度变快。

    DRF给我们提供了三种分页方式,我们看下他们都是什么样的~~

    分页组件的使用

    DRF提供的三种分页

    drf 内置分页器 有几种方式 只有获取多条数据时才有用

    方式1

    定义配置文件settings

    REST_FRAMEWORK = {
        "PAGE_SIZE":2,#代表2
    }
    

    modul

    原来的

    url

    from django.conf.urls import url
    from django.contrib import admin
    from api import views
    urlpatterns = [
        # 分页
        url(r'^page/article/$', views.PageArticleView.as_view()),
    
        url(r'^page/view/article/$', views.PageViewArticleView.as_view()),
    ]
    
    

    view

    from rest_framework.pagination import PageNumberPagination
    from rest_framework.pagination import LimitOffsetPagination
    from rest_framework import serializers
    
    class PageArticleSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Article
            fields = "__all__"
    
    class PageArticleView(APIView):
        def get(self,request,*args,**kwargs):
            queryset = models.Article.objects.all()
    
            # 方式一:仅数据
            #分页对象
            page_object = PageNumberPagination()
            # 调用 分页对象.paginate_queryset方法进行分页,得到的结果是分页之后的数据
    		# result就是分完页的一部分数据
            result = page_object.paginate_queryset(queryset,request,self)
            
            # 序列化分页之后的数据
            ser = PageArticleSerializer(instance=result,many=True)
            return Response(ser.data)
    
    

    方式2

    from rest_framework.pagination import PageNumberPagination
    from rest_framework.pagination import LimitOffsetPagination
    from rest_framework import serializers
    
    class PageArticleSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Article
            fields = "__all__"
    
    class PageArticleView(APIView):
        def get(self,request,*args,**kwargs):
            queryset = models.Article.objects.all()
    
            # 方式二:数据 + 分页信息
            page_object = PageNumberPagination()
            result = page_object.paginate_queryset(queryset, request, self)
            ser = PageArticleSerializer(instance=result, many=True)
            return page_object.get_paginated_response(ser.data)
    
    

    方式3

    from rest_framework.pagination import PageNumberPagination#第1种方式
    from rest_framework.pagination import LimitOffsetPagination
    #第2种方式
    from rest_framework import serializers
    
    class PageArticleSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Article
            fields = "__all__"
    
    class PageArticleView(APIView):
        def get(self,request,*args,**kwargs):
            queryset = models.Article.objects.all()
    
         # 方式三:数据 + 部分分页信息
            page_object = PageNumberPagination()
            result = page_object.paginate_queryset(queryset, request, self)
            ser = PageArticleSerializer(instance=result, many=True)
            return Response({'count':page_object.page.paginator.count,'result':ser.data})
    

    分页的另一种方式

    from rest_framework.pagination import PageNumberPagination
    from rest_framework.pagination import LimitOffsetPagination
    from rest_framework import serializers
    
    class PageArticleSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Article
            fields = "__all__"
            
    #重 定义  防止 一次取过多    
    class HulaLimitOffsetPagination(LimitOffsetPagination):
        max_limit = 20
            
            
    class PageArticleView(APIView):
        def get(self,request,*args,**kwargs):
            queryset = models.Article.objects.all()
            
    #就是类不同
            page_object = HulaLimitOffsetPagination()
            result = page_object.paginate_queryset(queryset, request, self)
            ser = PageArticleSerializer(instance=result, many=True)
            return Response(ser.data)
    

    分页出现的警告问题 了解

    url

    from django.conf.urls import url
    from django.contrib import admin
    from api import views
    urlpatterns = [
        url(r'^page/view/article/$', views.PageViewArticleView.as_view()),
    ]
    

    seting

    REST_FRAMEWORK = {
        "PAGE_SIZE":2,#代表2
    	"DEFAULT_PAGINATION_CLASS":"rest_framework.pagination.PageNumberPagination"#为什么要配置
    }
    

    view

    from rest_framework.generics import ListAPIView 
    class PageViewArticleSerializer(serializers.ModelSerializer):
        
        class Meta: model = models.Article 
            fields = "__all__" 
    class PageViewArticleView(ListAPIView): 
        queryset = models.Article.objects.all() 
        serializer_class = PageViewArticleSerializer
    

    总结

    drf 有分页功能  对查询的数据自动分页  有3种方法
    
  • 相关阅读:
    C# SocketAsyncEventArgs Server
    C# Socket 入门5 UPD 结构体 与 C++ 通信
    如何取得 Func 对象 字段
    动态调用对象的属性和方法——性能和灵活性兼备的方法
    C# 读写锁 ReaderWriteLock
    C# IP多播
    C# 广播通信
    程序员那点儿事
    wince上数据库:sqlce和sqlite
    evc vc字符串转换处理
  • 原文地址:https://www.cnblogs.com/saoqiang/p/12419615.html
Copyright © 2011-2022 走看看