序列化
1.models部分
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") authors=models.ManyToManyField("Author") def __str__(self): return self.title class Publish(models.Model): name=models.CharField(max_length=32) email=models.EmailField() def __str__(self): return self.name class Author(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() def __str__(self): return self.name
2.views部分
from rest_framework.views import APIView from rest_framework.response import Response from .models import * from django.shortcuts import HttpResponse from django.core import serializers from rest_framework import serializers class BookSerializers(serializers.Serializer): title=serializers.CharField(max_length=32) price=serializers.IntegerField() pub_date=serializers.DateField() publish=serializers.CharField(source="publish.name") #authors=serializers.CharField(source="authors.all") authors=serializers.SerializerMethodField() def get_authors(self,obj): temp=[] for author in obj.authors.all(): temp.append(author.name) return temp class BookViewSet(APIView): def get(self,request,*args,**kwargs): book_list=Book.objects.all() # 序列化方式1: # from django.forms.models import model_to_dict # import json # data=[] # for obj in book_list: # data.append(model_to_dict(obj)) # print(data) # return HttpResponse("ok") # 序列化方式2: # data=serializers.serialize("json",book_list) # return HttpResponse(data) # 序列化方式3: bs=BookSerializers(book_list,many=True) return Response(bs.data)
ModelSerializer
class BookModelSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" def create(self, validated_data): authors = validated_data.pop('authors') obj = Book.objects.create(**validated_data) obj.authors.add(*authors) return obj
提交post请求
def post(self,request,*args,**kwargs): bs=BookSerializers(data=request.data,many=False) if bs.is_valid(): # print(bs.validated_data) bs.save() return Response(bs.data) else: return HttpResponse(bs.errors)
重写save中的create方法
class BookSerializers(serializers.ModelSerializer): class Meta: model=Book fields="__all__" # exclude = ['authors',] # depth=1 def create(self, validated_data): authors = validated_data.pop('authors') obj = Book.objects.create(**validated_data) obj.authors.add(*authors) return obj
单条数据的get和post请求
class BookDetailViewSet(APIView): def get(self,request,pk): book_obj=Book.objects.filter(pk=pk).first() bs=BookSerializers(book_obj) return Response(bs.data) def put(self,request,pk): book_obj=Book.objects.filter(pk=pk).first() bs=BookSerializers(book_obj,data=request.data) if bs.is_valid(): bs.save() return Response(bs.data) else: return HttpResponse(bs.errors)
超链接API:Hyperlinked
class BookSerializers(serializers.ModelSerializer): publish= serializers.HyperlinkedIdentityField( view_name='publish_detail', lookup_field="publish_id", lookup_url_kwarg="pk") class Meta: model=Book fields="__all__" #depth=1
urls部分:
urlpatterns = [ path('books/', views.BookViewSet.as_view(), name='book_list'), re_path('books/(?P<pk>d+)', views.BookDetailViewSet.as_view(), name='book_detail') path('publishers/', views.PublishViewSet.as_view(), name='publish_list') re_path('publishers/(?P<pk>d+)', views.PublishDetailViewSet.as_view(), name='publish_detail') ]
使用混合
views.py
from rest_framework.views import APIView from rest_framework.response import Response from .models import * from django.shortcuts import HttpResponse from django.core import serializers from rest_framework import serializers class BookSerializers(serializers.ModelSerializer): class Meta: model=Book fields="__all__" #depth=1 class PublshSerializers(serializers.ModelSerializer): class Meta: model=Publish fields="__all__" depth=1 class BookViewSet(APIView): def get(self,request,*args,**kwargs): book_list=Book.objects.all() bs=BookSerializers(book_list,many=True,context={'request': request}) return Response(bs.data) def post(self,request,*args,**kwargs): print(request.data) bs=BookSerializers(data=request.data,many=False) if bs.is_valid(): print(bs.validated_data) bs.save() return Response(bs.data) else: return HttpResponse(bs.errors) class BookDetailViewSet(APIView): def get(self,request,pk): book_obj=Book.objects.filter(pk=pk).first() bs=BookSerializers(book_obj,context={'request': request}) return Response(bs.data) def put(self,request,pk): book_obj=Book.objects.filter(pk=pk).first() bs=BookSerializers(book_obj,data=request.data,context={'request': request}) if bs.is_valid(): bs.save() return Response(bs.data) else: return HttpResponse(bs.errors) class PublishViewSet(APIView): def get(self,request,*args,**kwargs): publish_list=Publish.objects.all() bs=PublshSerializers(publish_list,many=True,context={'request': request}) return Response(bs.data) def post(self,request,*args,**kwargs): bs=PublshSerializers(data=request.data,many=False) if bs.is_valid(): # print(bs.validated_data) bs.save() return Response(bs.data) else: return HttpResponse(bs.errors) class PublishDetailViewSet(APIView): def get(self,request,pk): publish_obj=Publish.objects.filter(pk=pk).first() bs=PublshSerializers(publish_obj,context={'request': request}) return Response(bs.data) def put(self,request,pk): publish_obj=Publish.objects.filter(pk=pk).first() bs=PublshSerializers(publish_obj,data=request.data,context={'request': request}) if bs.is_valid(): bs.save() return Response(bs.data) else: return HttpResponse(bs.errors)
mixin类编写视图
from rest_framework import mixins from rest_framework import generics class BookViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializers def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) class BookDetailViewSet(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializers def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs)
使用通用的基于类的视图
views.py
from rest_framework import mixins from rest_framework import generics class BookViewSet(generics.ListCreateAPIView): queryset = Book.objects.all() serializer_class = BookSerializers class BookDetailViewSet(generics.RetrieveUpdateDestroyAPIView): queryset = Book.objects.all() serializer_class = BookSerializers class PublishViewSet(generics.ListCreateAPIView): queryset = Publish.objects.all() serializer_class = PublshSerializers class PublishDetailViewSet(generics.RetrieveUpdateDestroyAPIView): queryset = Publish.objects.all() serializer_class = PublshSerializers
viewsets.ModelViewSet
urls.py
path(r'^books/$', views.BookViewSet.as_view({"get":"list","post":"create"}),name="book_list"), re_path(r'^books/(?P<pk>d+)$', views.BookViewSet.as_view({ 'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy' }),name="book_detail"),
views.py
class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializers
认证组件
1.写一个认证类
from rest_framework.authentication import BaseAuthentication class UserAuth(BaseAuthentication): def authenticate(): pass //通过 1.拿到用户传递的token 2.拿到数据里面的token与用户传递的token进行比较 //不通过 raise ApiException("message")
2.在视图中指定认证类
class BookView(APIView): authentication_classes = [userAuth] //可以指定多个认证类,如果需要返回数据,在最后一个认证类中返回
3.全局认证
在settings文件中指定 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES":["app01.utils.TokenAuth"] }
权限组件
1.写一个权限类
from rest_framework.permissions import BasePermission class UserPerm(BasePermission): message = "没有权限" def has_permission(self, request, view): username = request.user user_type = User.objects.filter(name=username).first().user_type if user_type == 3: return True return False
2.指定权限类
class BookView(APIView): permission_classes = [UserPerm]
频率组件
1.定义一个频率类
from rest_framework.throttling import SimpleRateThrottle class RateThrottle(SimpleRateThrottle): rate = "5/m" def get_cache_key(self, request, view): return self.get_ident(request)
url注册器
导入模块 from django.urls import re_path, include from rest_framework import routers from app01 import views
生成一个注册器实例对象
router = routers.DefaultRouter()
将需要自动生成url的接口注册 router.register("books", views.BookView)
开始自动生成url urlpatterns = [ re_path('^', include(router.urls)) ]
响应器组件
导入模块 from rest_framework.renderers import JSONRenderer 使用 class BookView(ModelViewSet): renderer_classes = [JSONRenderer] queryset = Book.objects.all() serializer_class = BookSerializer 浏览器再次访问接收到的就是普通的json格式的数据
分页器组件
导入模块 from rest_framework.pagination import PageNumberPagination 获取数据 books = Book.objects.all() 创建分页器 paginater = PageNumberPagination() 开始分页 paged_books = paginater.paginate_queryset(books, request) 将分页后的数据进行序列化 serialized_data = BookSerializer(paged_books, many=True) 返回数据 return Response(serialized_data.data)
自定义分页器
class MyPagination(PageNumberPagination):
page_size = 2
page_query_param = "p"
page_size_query_param = "size"
max_page_size = 5