類的約束
繼承 必須繼續 定義 不然報錯
# 約束子類中必須實現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種方法