DRF中的request
在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等。
比如,区别于Django中的request从request.GET中获取URL参数,从request.POST中取某些情况下的POST数据。
在APIView中封装的request,就实现了请求数据的解析:
对于GET请求的参数我们通过request.query_params来获取。
对于POST请求、PUT请求的数据我们通过request.data来获取。
视图的使用:
1 前提之序列化
# 首先需要在setting中注册rest_framework的中间件 from rest_framework import serializers from crm import models class PublisherModel(serializers.ModelSerializer): class Meta: model =models.Publisher fields = '__all__' class AuthorModel(serializers.ModelSerializer): class Meta: model = models.Author fields = '__all__' class BookSerializers(serializers.Serializer): id = serializers.IntegerField(required=False) name = serializers.CharField(max_length=32) pub_date = serializers.DateField() CHOICES = ((1, 'python'), (2, 'go语言'), (3, 'linux')) # source设置数据读取时候读取到 CHOICES里面的内容,read_only设置只在读取时有效 category = serializers.CharField(source='get_category_display',read_only=True) post_category = serializers.IntegerField(write_only=True) # 对出版社字段进行校验 读取时,和设置是显示的格式不同 publisher = PublisherSerializers(read_only=True) post_publisher = serializers.IntegerField(write_only=True) # 对作者字段进行校验 author = AuthorSerializers(many=True, read_only=True) post_author = serializers.ListField(write_only=True) # create方法相当于对每个通过校验的字段进行获取在数据库中新建保存 def create(self, validated_data): # validated_data里面保存的是校验通过后的数据 book_obj = models.Book.objects.create( name=validated_data["name"], pub_date=validated_data["pub_date"], category=validated_data["post_category"], publisher_id=validated_data["post_publisher"] ) book_obj.author.set(validated_data["post_author"]) # 多对多字段需要重新设置关系 return book_obj def update(self, instance, validated_data): # 从validated_data中取出数据挨个字段更新 instance.name = validated_data.get('name', instance.name) instance.pub_date = validated_data.get('pub_date', instance.pub_date) instance.category = validated_data.get('post_category', instance.category) instance.publisher_id = validated_data.get('post_publisher', instance.publisher_id) instance.save() # 更新多对多字段的 authors # 先取出当前书籍的所有作者id author_list = instance.author.all().values_list('id') # [(1,),(2,)] ==> [1, 2] instance.author.set(validated_data.get('post_authors', [i[0] for i in author_list])) return instance
2 初级阶段
from rest_framework.response import Response from rest_framework.views import APIView # 图书的展示以及添加 class Book(APIView): # 继承改为restframework的封装的APIView def get(self, request): # 1,在后端获取数据 book_obj = models.Book.objects.all() # 2,使用seriallizers进行数据格式化 ser_obj = BookSerializers(book_obj, many=True) # 返回给前端 Response方法是serializers封装的方法 return Response(ser_obj.data) def post(self, request): # 1, 在前端获取提交的数据 # 此时的request已经是被serializers封装过的request,不是简单的页面提交的那个request # 前端提交的数据存在request.data里面 print(request.data) # 2, 进行serializers校验 ser_obj = BookSerializers(data=request.data) if ser_obj.is_valid(): # 如果通过了校验 print("oye") # 数据校验通过以后,想要使用save方法保存的话,需要调用BookSerializers里面的create方法 ser_obj.save() return Response('数据添加成功!') else: # 没通过校验的数据,返回错误信息 print('ono') return Response(ser_obj.errors) # 具体图书信息的展示以及修改和删除 class BookDetail(APIView): def get(self, request, pk): book_obj = models.Book.objects.filter(pk=pk).first() if book_obj: ser_obj = BookModel(book_obj) # 对数据进行有效性校验 return Response(ser_obj.data) else: return Response('无效的id') def put(self, request, pk): book_obj = models.Book.objects.filter(pk=pk).first() if book_obj: ser_obj = BookSerializers(instance=book_obj, data=request.data, partial=True) # 此处得到request已经是封装过的,partial表示局部更新 if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.data) else: return Response(ser_obj.errors) else: return Response('无效的id') def delete(self,request,pk): book_obj = models.Book.objects.filter(pk=pk).first() if book_obj: book_obj.delete() return Response("删除成功") else: return Response("无效的id")
3 强化版
from django.contrib import admin from django.urls import path,re_path from crm import views urlpatterns = [ path('admin/', admin.site.urls), path('book/', views.Book.as_view()), re_path('book/(?P<pk>d+)/$', views.BookDetail.as_view()), path('author/', views.Authorshow.as_view()), re_path('author/(?P<pk>d+)/$', views.AuthorDetail.as_view()), path('publisher/', views.Publishershow.as_view()), re_path('publisher/(?P<pk>d+)', views.PublisherDetail.as_view()), ]
# 公共类,获取数据使用 class GerneridView(APIView): queryset = None serializer_class = None def get_queryset(self): queryset = self.queryset.all() # 刷新数据 return queryset def get_object(self, request, pk, *args, **kwargs): queryset = self.queryset.filter(pk=pk).first() return queryset class ListMixin(object): def get(self, request): queryset = self.get_queryset() ser_obj = self.serializer_class(queryset, many=True) return Response(ser_obj.data) class CreateMixin(object): def post(self, request): ser_obj = self.serializer_class(data=request.data) if ser_obj.is_valid(): ser_obj.save() return Response('OK') else: return Response(ser_obj.errors) class ActreveMixin(object): def get(self, request, pk, *args, **kwargs): obj = self.get_object(request, pk, *args, **kwargs) if obj: ser_obj = self.serializer_class(obj) return Response(ser_obj.data) else: return Response("无效的id") class UpdateMixin(object): def put(self, request, pk, *args, **kwargs): book_obj = self.get_object(request, pk, *args, **kwargs) if book_obj: ser_obj = AuthorModel(instance=book_obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response("数据更新成功") else: return Response(ser_obj.errors) else: return Response("无效的id") class DelMixin(object): def delete(self,request, pk, *args, **kwargs): obj = self.get_object(request, pk, *args, **kwargs) if obj: obj.delete() return Response('删除成功') else: return Response("无效的id") class Authorshow(GerneridView, ListMixin, CreateMixin): queryset = models.Author.objects.all() serializer_class = AuthorModel class AuthorDetail(GerneridView, ActreveMixin, UpdateMixin, DelMixin): queryset =models.Author.objects.all() serializer_class = AuthorModel
4 究极进化版
from django.urls import path,re_path from bms import views urlpatterns = [ path('admin/', admin.site.urls), # 作者相关操作 path('author/', views.AuthorShow.as_view(actions={'get': 'list', 'post': 'create'})), re_path('author/(?P<pk>d+)/$', views.AuthorShow.as_view(actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})), # 出版社相关操作 path('publisher/', views.PublisherShow.as_view(actions={'get': 'list', 'post': 'create'})), re_path('publisher/(?P<pk>d+)/$', views.PublisherShow.as_view(actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})), # 图书相关增删改查操作 path('books/', views.BooksShow.as_view(actions={'get': 'list', 'post': 'create'})), re_path('books/(?P<pk>d+)/$', views.BooksShow.as_view(actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})), ]
from bms import models # Create your views here. from rest_framework.viewsets import ModelViewSet from bms.serializer import AuthorModel, PublisherModel, BookModel class AuthorShow(ModelViewSet): queryset = models.Author.objects.all() serializer_class = AuthorModel class PublisherShow(ModelViewSet): queryset = models.Publisher.objects.all() serializer_class = PublisherModel class BooksShow(ModelViewSet): queryset = models.Book.objects.all() serializers = BookModel
5 无比强大的路由
from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register(r'school', views.SchoolView) urlpatterns += router.urls