views.pyfrom django.shortcuts import render
from .models import *
# Create your views here. from rest_framework import serializers from rest_framework.views import APIView from rest_framework.response import Response class PublisherSerializers(serializers.Serializer): name = serializers.CharField() email = serializers.CharField() # class BookSerializers(serializers.Serializer): # title = serializers.CharField() # price = serializers.IntegerField() # pub_date = serializers.DateField() # publisher = serializers.CharField(source="publisher.email") # # authors = serializers.CharField(source="authors.all") #多对多不好用 # authors =serializers.SerializerMethodField() # def get_authors(self,obj): # temp = [] # for obj in obj.authors.all(): # temp.append(obj.name) # print(temp) # return temp class PublishSeria(serializers.ModelSerializer): class Meta: model = Publish fields = "__all__" class BookSeria(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" #显示超链接 publish = serializers.HyperlinkedIdentityField( view_name='publish_detail', lookup_field="publish_id", lookup_url_kwarg="pk") # 改成连接之后,重新增加book表的话会出错,显示找不到publish_id #自定义显示字段 可以不加,不加自定义字段就显示全部字段 用自定义的话post请求要重写create方法 # publisher = serializers.CharField(source="publisher.pk",read_only=True)#一对多可以用 自定义字段 # authors = serializers.CharField(source="authors.all") #多对多不好用 #多对多用下面这个 # authors =serializers.SerializerMethodField() 自定义字段 # def get_authors(self,obj): # temp = [] # for obj in obj.authors.all(): # temp.append(obj.name) # print(temp) # return temp # 自定义显示字段 用自定义的话post请求要重写create方法,不自定义用默认的就不需要create方法 # def create(self, validated_data): # print("validated_data",validated_data) # book = Book.objects.create(title=validated_data["title"],price=validated_data["price"],pub_date=validated_data["pub_date"],publisher_id=validated_data["publisher"]["pk"]) # book.authors.add(*validated_data["authors"]) # return book class AuthorSeria(serializers.ModelSerializer): class Meta: model = Author fields = "__all__" # 第一种: 以APIView方式 #认证组件 验证用户名 局部验证 # from rest_framework import exceptions # from rest_framework.authentication import BaseAuthentication # class UserTokenCheck(BaseAuthentication): # def authenticate(self,request): # token = request.GET.get("token") # token_obj = UserToken.objects.filter(token=token).first() # if not token_obj: # raise exceptions.AuthenticationFailed("验证失败") # else: # return token_obj.userinfo.name,token_obj.token #如果继承于BaseAuthentication,authenticate_header就不用写了 #如果不继承就要加上 # def authenticate_header(self,request): # pass #解析器---> 无论post(请求)前面传的是JSON数据还是urlencoded数据,rest framework 中的request.data都帮我们解析成字典,而django中的request.POST只解析urlencode数据 from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParser #默认使用前三个解析器
在视图类中添加 parser_classes = [JSONPaser,] #如果只写这一个,意味着只能解析JSON数据 FormParser解析urlencode数据
默认parser_classes = [JSONParser,FormParser]这两个够用
#分页 from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination class MyPageNumberPagination(PageNumberPagination):
page_size = 2 #每页显示多少条数据
page_query_param = "page" #URL中输入的 page=2
page_size_query_param = "size" #临时浏览器中使用127.0.0.1:8000/books/?page=2&size=2 第二页显示两条数据
max_page_size = 3 #上面的size最大值,不能无限制显示10000条数据 class MyLimitOffsetPagination(LimitOffsetPagination): default_limit = 1 class BookView(APIView): # authentication_classes = [UserTokenCheck,] def get(self,request,): book_list = Book.objects.all() # 分页***************** # page_num = MyPageNumberPagination() page_num = MyLimitOffsetPagination() books_pagenum = page_num.paginate_queryset(book_list, request, self) bs = BookSeria(books_pagenum, many=True, context={"request": request}) # bs = BookSeria(book_list,many=True) # bs = BookSeria(book_list, many=True,context={"request":request}) bookser = BookSeria(book_list,many=True,context={'request': request}) return Response(bookser.data) def post(self,request): print(request.data) bookser = BookSeria(data=request.data,context={'request': request}) print(bookser) if bookser.is_valid(): bookser.save() return Response(bookser.data) else: return Response(bookser.errors) class BookDetailView(APIView): def get(self,request,pk): book_obj = Book.objects.filter(pk=pk).first() bookser = BookSeria(book_obj,context={'request': request}) return Response(bookser.data) def put(self,request,pk): book_obj = Book.objects.filter(pk=pk).first() bookser = BookSeria(book_obj, data=request.data,context={'request': request}) print(bookser) if bookser.is_valid(): bookser.save() return Response(bookser.data) else: return Response(bookser.errors) def delete(self,request,pk): Book.objects.filter(pk=pk).first().delete() return Response() class PublishView(APIView): def get(self, request, *args, **kwargs): publish_list = Publish.objects.all() bs = PublishSeria(publish_list, many=True, context={'request': request}) return Response(bs.data) def post(self, request, *args, **kwargs): bs = PublishSeria(data=request.data, many=False) if bs.is_valid(): # print(bs.validated_data) bs.save() return Response(bs.data) else: return Response(bs.errors) class PublishDetailView(APIView): def get(self, request, pk): publish_obj = Publish.objects.filter(pk=pk).first() bs = PublishSeria(publish_obj, context={'request': request}) return Response(bs.data) def put(self, request, pk): publish_obj = Publish.objects.filter(pk=pk).first() bs = PublishSeria(publish_obj, data=request.data, context={'request': request}) if bs.is_valid(): bs.save() return Response(bs.data) else: return Response(bs.errors) # # # 第二种 通过mixins generics # # from rest_framework import mixins # from rest_framework import generics # class BookView(mixins.ListModelMixin, # mixins.CreateModelMixin, # generics.GenericAPIView): # # queryset = Book.objects.all() # serializer_class = BookSeria # # def get(self,request,*args,**kwargs): # # return self.list(request,*args,**kwargs) # # def post(self, request, *args, **kwargs): # print("===========") # print(request.data) # return self.create(request, *args, **kwargs) # # class BookDetailView(mixins.RetrieveModelMixin, # mixins.UpdateModelMixin, # mixins.DestroyModelMixin, # generics.GenericAPIView): # queryset = Book.objects.all() # serializer_class = BookSeria # 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) # # class PublishView(mixins.ListModelMixin, # mixins.CreateModelMixin, # generics.GenericAPIView): # # queryset = Publish.objects.all() # serializer_class = PublishSeria # # def get(self,request,*args,**kwargs): # # return self.list(request,*args,**kwargs) # # def post(self, request, *args, **kwargs): # print("===========") # print(request.data) # return self.create(request, *args, **kwargs) # # class PublishDetailView(mixins.RetrieveModelMixin, # mixins.UpdateModelMixin, # mixins.DestroyModelMixin, # generics.GenericAPIView): # # queryset = Publish.objects.all() # serializer_class = PublishSeria # 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) #第三种 简化通用类视图 # class BookView(generics.ListCreateAPIView): # # queryset = Book.objects.all() # serializer_class = BookSeria # # class BookDetailView(generics.RetrieveUpdateDestroyAPIView): # queryset = Book.objects.all() # serializer_class = BookSeria # class PublishView(generics.ListCreateAPIView): # # queryset = Publish.objects.all() # serializer_class = PublishSeria # # class PublishDetailView(generics.RetrieveUpdateDestroyAPIView): # queryset = Publish.objects.all() # serializer_class = PublishSeria # #第四种 # from rest_framework import viewsets # class BookViewSet(viewsets.ModelViewSet): # queryset = Book.objects.all() # serializer_class = BookSeria # #权限组件 # from rest_framework.permissions import BasePermission # class SVIPPermission(BasePermission): #继承于BasePermission,/authous/2/才能查看每个具体的作者。否则报错 # message = "只有超级用户才能访问" # def has_permission(self,request,view): # username = request.user # print(username) # user_type = UserInfo.objects.filter(name=username).first().user_type # if user_type == 3: # return True # else: # return False # from book.service import SVIPPermission from rest_framework import viewsets
#*********频率组件********* from rest_framework.throttling import BaseThrottle VISIT_RECORD={} class VisitThrottle(BaseThrottle): def __init__(self): self.history=None def allow_request(self,request,view): remote_addr = request.META.get('REMOTE_ADDR') print(remote_addr) import time ctime=time.time() if remote_addr not in VISIT_RECORD: VISIT_RECORD[remote_addr]=[ctime,] return True history=VISIT_RECORD.get(remote_addr) self.history=history while history and history[-1]<ctime-60: history.pop() if len(history)<10: history.insert(0,ctime) return True else: return False def wait(self): import time ctime=time.time() return 60-(ctime-self.history[-1]) class AuthorViewSet(viewsets.ModelViewSet): # authentication_classes = [UserTokenCheck, ] #局部验证 # permission_classes = [SVIPPermission,] throttle_classes = [VisitThrottle] pagination_class = MyPageNumberPagination queryset = Author.objects.all() serializer_class = AuthorSeria #生成随机token def get_random_Str(name): import hashlib,time currenttime = str(time.time()) md5 = hashlib.md5(bytes(name,encoding="utf-8"))
md5.update(bytes(ctime,encoding='utf-8')) return md5.hexdigest() #用户登录 import json from django.http import JsonResponse class LoginView(APIView): authentication_classes = [] #全局配置后,不让login验证,直接加空列表就不验证 def post(self,request): print(request.data) name = request.data.get("name") pwd = request.data.get("pwd") user_obj = UserInfo.objects.filter(name=name,pwd=pwd).first() ret = {"status":"1000","msg":"验证成功"} if user_obj: random_str = get_random_Str(user_obj.name) UserToken.objects.update_or_create(userinfo=user_obj,defaults={"token":random_str}) ret["token"]=random_str else: ret["status"] = 404 ret["msg"] = "用户名或者密码错误" return JsonResponse(ret) return Response(json.dumps(ret,ensure_ascii=False))
settings.py
#全局配置验证 REST_FRAMEWORK = { # "DEFAULT_AUTHENTICATION_CLASSES":["book.service.UserTokenCheck"], # "DEFAULT_PERMISSION_CLASSES":["book.service.SVIPPermission"], "PAGE_SIZE":1 }
urls.py
from django.conf.urls import url,include from django.contrib import admin from book import views #URL路由分发 from rest_framework import routers routers=routers.DefaultRouter() routers.register("authors",views.AuthorViewSet) #会自动添加以下地址 # ^authors/$ [name='author-list'] # ^authors\.(?P<format>[a-z0-9]+)/?$ [name='author-list'] # ^authors/(?P<pk>[^/.]+)/$ [name='author-detail'] # ^authors/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='author-detail'] urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^books/$',views.BookView.as_view()), url(r'^books/(?P<pk>\d+)/',views.BookDetailView.as_view()), url(r'^publish/$',views.PublishView.as_view()), url(r'^publish/(?P<pk>\d+)/',views.PublishDetailView.as_view(),name="publish_detail"), #第四种 # url(r'^books/$', views.BookViewSet.as_view({"get": "list", "post": "create"}), name="book_list"), # url(r'^books/(?P<pk>\d+)/$', views.BookViewSet.as_view({'get': 'retrieve', # 'put': 'update','patch': 'partial_update', # 'delete': 'destroy'}), name="book_detail"), url(r'^authors/$', views.AuthorViewSet.as_view({"get": "list", "post": "create"}), name="author_list"), url(r'^authors/(?P<pk>\d+)/$', views.AuthorViewSet.as_view({'get': 'retrieve', 'put': 'update','patch': 'partial_update', 'delete': 'destroy'}), name="author_detail"), url(r'^login/$', views.LoginView.as_view(), name="login"), ]