多对多表的增删改查与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种方法
上一篇:视频识别函数##


下一篇:python串口通信