一、视图三部曲

https://www.cnblogs.com/wupeiqi/articles/7805382.html

使用混合(mixins)

之前得视图部分

# urls.pyfrom django.conf.urls import url
from django.contrib import adminfrom app01 import viewsurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^publishes/$', views.PublishView.as_view(),name="publish"),url(r'^publishes/(?P<pk>\d+)/$', views.PublishDetailView.as_view(),name="detail_publish"),url(r"^books/$", views.BookView.as_view(),name="books"),url(r'^books/(?P<pk>\d+)/$',views.BookDetailView.as_view(),name="detail_book")]------------------------------------------------------# views.pyfrom rest_framework.views import APIView, Response
from app01.serializers import *class PublishView(APIView):def get(self, request):publish_list = Publish.objects.all()ret = PublishModelSerializers(publish_list, many=True)return Response(ret.data)def post(self, request):ps = PublishModelSerializers(data=request.data)if ps.is_valid():ps.save()return Response(ps.data)else:return Response(ps.errors)class PublishDetailView(APIView):def get(self,request,pk):publish = Publish.objects.filter(pk=pk).first()ps = PublishModelSerializers(publish)return Response(ps.data)def put(self,request,pk):publish = Publish.objects.filter(pk=pk).first()ps = PublishModelSerializers(publish,data=request.data)if ps.is_valid():ps.save()return Response(ps.data)else:return Response(ps.errors)def delete(self,request,pk):Publish.objects.filter(pk=pk).delete()return Response()class BookView(APIView):def get(self, request):book_list = Book.objects.all()ret = BookModelSerializers(book_list, many=True,context={"request":request})return Response(ret.data)def post(self, request):bms = BookModelSerializers(data=request.data, many=False,context={"request":request})if bms.is_valid():bms.save()return Response(bms.data)else:return Response(bms.errors)class BookDetailView(APIView):def get(self,request,pk):book = Book.objects.filter(pk=pk).first()# 序列化bms = BookModelSerializers(book,context={"request":request})return Response(bms.data)def put(self,request,pk):book = Book.objects.filter(pk=pk).first()bms = BookModelSerializers(book,data=request.data,context={"request":request})if bms.is_valid():bms.save()return Response(bms.data)else:return Response(bms.errors)def delete(self,reqeust,pk):Book.objects.filter(pk=pk).delete()return Response()---------------------------------------------------
# serializers.py# -*- coding:utf-8 -*-
from .models import *
from rest_framework import serializersclass PublishModelSerializers(serializers.ModelSerializer):class Meta:model = Publishfields = "__all__"class BookModelSerializers(serializers.ModelSerializer):class Meta:model = Bookfields = "__all__"

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.titleclass Publish(models.Model):name = models.CharField(max_length=32)email = models.EmailField()def __str__(self):return self.nameclass Author(models.Model):name = models.CharField(max_length=32)age = models.IntegerField()def __str__(self):return self.name

models.py

1. mixin类编写视图

from rest_framework import mixins, generics

mixins.ListModelMixin,   mixins.CreateModelMixin,

mixins.RetrieveModelMixin,   mixins.UpdateModelMixin,   mixins.DestroyModelMixin,

generics.GenericAPIView

   url(r'^authors/$',views.AuthorView.as_view(),name="author"),url(r'^authors/(?P<pk>\d+)',views.AuthorDetailView.as_view(),name="detail_author"),-----------------------------------------#########################   mixin类编写视图  ##############################from rest_framework import mixins, genericsclass AuthorView(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):queryset = Author.objects.all()serializer_class = AuthorModelSerializersdef get(self, request, *args, **kwargs):return self.list(request, *args, **kwargs)def post(self, request, *args, **kwargs):return self.create(request, *args, **kwargs)class AuthorDetailView(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin,generics.GenericAPIView):queryset = Author.objects.all()serializer_class = AuthorModelSerializersdef 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 AuthorModelSerializers(serializers.ModelSerializer):class Meta:model = Authorfields = "__all__"

2. 使用通用的基于类的视图

from rest_framework import generics

generics.ListCreateAPIView

generics.RetrieveUpdateDestroyAPIView

通过使用mixin类,我们使用更少的代码重写了这些视图,但我们还可以再进一步。REST框架提供了一组已经混合好(mixed-in)的通用视图,我们可以使用它来简化我们的views.py模块。

#########################   使用通用得基于类得视图  ##############################from rest_framework import genericsclass AuthorView(generics.ListCreateAPIView):queryset = Author.objects.all()serializer_class = AuthorModelSerializersclass AuthorDetailView(generics.RetrieveUpdateDestroyAPIView):queryset = Author.objects.all()serializer_class = AuthorModelSerializers

3. viewsets.ModelViewSet

views.AuthorModelView.as_view({"get": "list", "post": "create"})

views.AuthorModelView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})

from rest_framework  import viewsets

viewsets.ModelViewSet

    url(r'^authors/$', views.AuthorModelView.as_view({"get": "list", "post": "create"}), name="author"),url(r'^authors/(?P<pk>\d+)',views.AuthorModelView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"}), name="detail_author"),---------------------------------------------------#########################   viewsets.ModelViewSet  ##############################from rest_framework import viewsetsclass AuthorModelView(viewsets.ModelViewSet):queryset = Author.objects.all()serializer_class = AuthorModelSerializers

  # 可重写,覆盖!    # def list(self,request,*args,**kwargs):pass

效果:

get  post  get  put  delete  都可访问!

  

http://www.cnblogs.com/yuanchenqi/articles/8719520.html
视图三部曲
5中方法: 查(全部) 查(单条) 增 删 改
逻辑封装起来了-----------------------------------class AuthorModelView(viewsets.ModelViewSet):queryset = Author.objects.all()serializer_class = AuthorModelSerializers(1):url(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}), name='author'),
(2):url(r'^authors/$', ViewSetMixin.as_view({"get":"list","post":"create"}), name='author'),
(3):url(r'^authors/$', ViewsetMixin.View, name='author'),一旦用户 get 方式 访问 authors:
ViewsetMixin.View():for method, action in actions.items(): # {"get":"list","post":"create"}handler = getattr(self, action)    # self.list  self.createsetattr(self, method, handler)     # self.get = self.list  self.post = self.create# getattr(self,"get")  # self.list# getattr(self,"post") # self.createreturn self.dispatch()APIView.dispatch():if request.method.lower() in self.http_method_names:handler = getattr(self,request.method.lower())response = handler(request,*args,**kwargs)  # self.list()return response(ViewSetMixin)

小总结 - 笔记

二、认证组件

生成随机字符串

import hashlib, timedef get_random_str(user):""" 生成随机 字符串 """ctime = str(time.time())md5 = hashlib.md5(bytes(user,encoding='utf-8'))md5.update(bytes(ctime,encoding="utf-8"))return md5.hexdigest()

update_or_create

#  update_or_create
Token.objects.update_or_create(user=user,defaults={"token":random_str})

返回json

# import json
# from  django.shortcuts import HttpResponse
# return HttpResponse(json.dumps(res,ensure_ascii=False))

# from django.http import JsonResponse
# return JsonResponse(res)return Response(res)

登录,生成随机token

url(r'^login/$', views.LoginView.as_view(), name="login")---------------------------------------------import hashlib, timedef get_random_str(user):""" 生成随机 字符串 """ctime = str(time.time())md5 = hashlib.md5(bytes(user,encoding='utf-8'))md5.update(bytes(ctime,encoding="utf-8"))return md5.hexdigest()class LoginView(APIView):def post(self,request):name = request.data.get("name")pwd = request.data.get("pwd")user = User.objects.filter(name=name,pwd=pwd).first()res = {"state_code":1000,"msg":None}if user:random_str = get_random_str(user.name)#  update_or_createToken.objects.update_or_create(user=user,defaults={"token":random_str})res["token"] = random_strelse:res["state_code"] = 1001 # 错误状态码res["msg"] = "用户名或密码错误"# import json# from  django.shortcuts import HttpResponse# return HttpResponse(json.dumps(res,ensure_ascii=False))# from django.http import JsonResponse# return JsonResponse(res)return Response(res)--------------------------------------------------------# models.py class User(models.Model):name = models.CharField(max_length=32)pwd = models.CharField(max_length=32)class Token(models.Model):user = models.OneToOneField("User")token = models.CharField(max_length=128)def __str__(self):return self.token

效果图:

 

登录验证 - 局部

authentication_classes = [TokenAuth]

from rest_framework import exceptions

from rest_framework.authentication import BaseAuthentication

def authenticate(self,request):

  ... ...

  if not token_obj:

     raise exceptions.AuthenticationFailed("验证失败")

  return (token_obj.user.name, token_obj)

from rest_framework import exceptions# class TokenAuth(object):
#     def authenticate(self,request):
#         token = request.GET.get("token")
#         token_obj = Token.objects.filter(token=token).first()
#         if not token_obj:
#             raise exceptions.AuthenticationFailed("验证失败")
#
#         return (token_obj.user.name, token_obj)
#
#     def authenticate_header(self,request):
#         passfrom rest_framework.authentication import BaseAuthenticationclass TokenAuth(BaseAuthentication):def authenticate(self,request):token = request.GET.get("token")token_obj = Token.objects.filter(token=token).first()if not token_obj:raise exceptions.AuthenticationFailed("验证失败")return (token_obj.user.name, token_obj)class BookView(APIView): authentication_classes = [TokenAuth]def get(self, request):book_list = Book.objects.all()ret = BookModelSerializers(book_list, many=True, context={"request": request})return Response(ret.data)def post(self, request):bms = BookModelSerializers(data=request.data, many=False, context={"request": request})if bms.is_valid():bms.save()return Response(bms.data)else:return Response(bms.errors)

登录验证 - 全局

settings 配置

  'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth']

# settings.py

REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth']
}-------------------------------------------
# app01.utilsfrom .models import *
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthenticationclass TokenAuth(BaseAuthentication):def authenticate(self,request):token = request.GET.get("token")token_obj = Token.objects.filter(token=token).first()if not token_obj:raise exceptions.AuthenticationFailed("验证失败")return (token_obj.user.name, token_obj)--------------------------------------------
# views.pyclass BookView(APIView):def get(self, request):book_list = Book.objects.all()ret = BookModelSerializers(book_list, many=True, context={"request": request})return Response(ret.data)def post(self, request):bms = BookModelSerializers(data=request.data, many=False, context={"request": request})if bms.is_valid():bms.save()return Response(bms.data)else:return Response(bms.errors)

-----------------------------------------
class AuthorModelView(viewsets.ModelViewSet): authentication_classes = []   # 加上这个,前提是全局有认证;加上这个,就走自己得,不认证了,自己没有,才走全局配置得!

    queryset = Author.objects.all()    serializer_class = AuthorModelSerializers

效果图:

     

三、权限组件

权限 - 局部

permission_classes = [SVIPPermission]

has_permission(self,request,view):pass   # 固定得写法,根据源码来写得!

authentication_classes = []                       # 登录页面 不需要验证,在全局配置得前提下

class AuthorModelView(viewsets.ModelViewSet):authentication_classes = [TokenAuth]  permission_classes = [SVIPPermission]queryset = Author.objects.all()serializer_class = AuthorModelSerializers----------------------------------------------
# app01.utils.SVIPPermission
class SVIPPermission(object):message = "只有超级用户才能访问"def has_permission(self,request,view):username = request.useruser_type = User.objects.filter(name=username).first().user_typeif user_type == 3:return Trueelse:return False----------------------------------------------class LoginView(APIView):authentication_classes = []......

权限 - 全局

settings配置:

  'DEFAULT_PERMISSION_CLASSES': ['app01.utils.SVIPPermission']

# settings.py

REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth'],'DEFAULT_PERMISSION_CLASSES': ['app01.utils.SVIPPermission']
}

效果图:

四、频率组件

局部视图throttle

class BookView(APIView):# authentication_classes = [TokenAuth]# permission_classes = [SVIPPermission]throttle_classes = [VisitRateThrottle]。。。  。。。 -----------------------------------------------from rest_framework.throttling import BaseThrottleVISIT_RECORD={}
class VisitThrottle(BaseThrottle):def __init__(self):self.history=Nonedef allow_request(self,request,view):remote_addr = request.META.get('REMOTE_ADDR')print(remote_addr)import timectime=time.time()if remote_addr not in VISIT_RECORD:VISIT_RECORD[remote_addr]=[ctime,]return Truehistory=VISIT_RECORD.get(remote_addr)self.history=historywhile history and history[-1]<ctime-60:history.pop()if len(history)<3:history.insert(0,ctime)return Trueelse:return Falsedef wait(self):import timectime=time.time()return 60-(ctime-self.history[-1])       

全局视图throttle

REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth'],'DEFAULT_PERMISSION_CLASSES': ['app01.utils.SVIPPermission'],'DEFAULT_THROTTLE_CLASSES': ['app01.utils.VisitThrottle'],
}

内置throttle类

REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth'],'DEFAULT_PERMISSION_CLASSES': ['app01.utils.SVIPPermission'],'DEFAULT_THROTTLE_CLASSES': ['app01.utils.VisitThrottle'],"DEFAULT_THROTTLE_RATES": {"visit_rate": "1/m",}
}------------------------------------from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):scope="visit_rate"def get_cache_key(self, request, view):return self.get_ident(request)

http://www.cnblogs.com/yuanchenqi/articles/8719520.html

五、解析器

from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParser
"""
默认得是 JSONParser FormParser MultiPartParser
"""class BookView(APIView):parser_classes = [JSONParser,FormParser]... 

request类

  django的request类和rest-framework的request类的源码解析

局部视图

from rest_framework.parsers import JSONParser,FormParser
class PublishViewSet(generics.ListCreateAPIView):parser_classes = [FormParser,JSONParser]queryset = Publish.objects.all()serializer_class = PublshSerializersdef post(self, request, *args, **kwargs):print("request.data",request.data)return self.create(request, *args, **kwargs)

全局视图

REST_FRAMEWORK={"DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],"DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",],"DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",],"DEFAULT_THROTTLE_RATES":{"visit_rate":"5/m",},"DEFAULT_PARSER_CLASSES":['rest_framework.parsers.FormParser',]
}

六、url路由控制

url(r'',include(routers.urls)),

from rest_framework import routers

routers = routers.DefaultRouter()

routers.register("authors",views.AuthorModelView)

# urls.pyfrom django.conf.urls import url,include
from django.contrib import adminfrom app01 import viewsfrom rest_framework import routers
routers = routers.DefaultRouter()
routers.register("authors",views.AuthorModelView)urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^publishes/$', views.PublishView.as_view(), name="publish"),url(r'^publishes/(?P<pk>\d+)/$', views.PublishDetailView.as_view(), name="detail_publish"),url(r"^books/$", views.BookView.as_view(), name="books"),url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view(), name="detail_book"),# url(r'^authors/$',views.AuthorView.as_view(),name="author"),# url(r'^authors/(?P<pk>\d+)',views.AuthorDetailView.as_view(),name="detail_author"),# url(r'^authors/$', views.AuthorModelView.as_view({"get": "list", "post": "create"}), name="author"),# url(r'^authors/(?P<pk>\d+)',#     views.AuthorModelView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"}), name="detail_author"),
url(r'',include(routers.urls)),url(r'^login/$', views.LoginView.as_view(), name="login")]------------------------------------------# views.pyfrom rest_framework import viewsetsclass AuthorModelView(viewsets.ModelViewSet):queryset = Author.objects.all()serializer_class = AuthorModelSerializers

效果图

  

七、分页

pnp = MyPageNumberPagination()

books_page = pnp.paginate_queryset(book_list,request,self)

from rest_framework.pagination import PageNumberPagination, LimitOffsetPaginationclass MyPageNumberPagination(PageNumberPagination):page_size = 2page_query_param = "page"page_size_query_param = "size"max_page_size = 2   # 限制 size 得大小 不能超过多少!!class MyLimitOffsetPagination(LimitOffsetPagination):default_limit = 1---------------------------class BookView(APIView):def get(self, request):
book_list = Book.objects.all()pnp = MyPageNumberPagination()# pnp = MyLimitOffsetPagination()
books_page = pnp.paginate_queryset(book_list,request,self)# ret = BookModelSerializers(book_list, many=True, context={"request": request})ret = BookModelSerializers(books_page, many=True)# return Response(ret.data)    
     return pnp.get_paginated_response(ret.data)

from rest_framework import viewsetsclass AuthorModelView(viewsets.ModelViewSet):queryset = Author.objects.all()serializer_class = AuthorModelSerializers pagination_class = MyPageNumberPagination

效果图

day991 CBV2 APIViewclass BookView(APIView):passurl(r'^books/$', views.BookView.as_view(),name="books"),url(r'^books/$', View类下的view,name="books"),一旦访问books/:  view(request)======APIView类下的dispatch()====请求方式对应的示例方法()3 def dispatch():#一 初始化操作# (1) 构建新的request:self.request=self.initial_request()# self.request._request# self.request.GET# self.request.data# (2) 执行组件# 认证,权限,频率# 认证:request.userself.initial(request, *args, **kwargs)====   # 认证组件
                        self.perform_authentication(request)==== request.user=====for authenticator in self.authenticators:  # [TokenAuth(),]try:user_auth_tuple = authenticator.authenticate(self)except exceptions.APIException:self._not_authenticated()raiseif user_auth_tuple is not None:self._authenticator = authenticatorself.user, self.auth = user_auth_tuplereturn# 权限组件
                        self.check_permissions(request)===========for permission in self.get_permissions():if not permission.has_permission(request, self):self.permission_denied(request, message=getattr(permission, 'message', None))# 频率组件
                        self.check_throttles(request)=============for throttle in self.get_throttles():  # [VisitRateThrottle(),]if not throttle.allow_request(request, self):self.throttled(request, throttle.wait()) # 受限制# 分发if request.method.lower() in self.http_method_names:handler = getattr(self,request.method.lower(),self.http_method_not_allowed)response = handler(request, *args, **kwargs)return response4 序列化组件class PublishSerializers(serializers.Serializer):name = serializers.CharField()email = serializers.CharField()class PublishModelSerializers(serializers.ModelSerializer):class Meta:model=Publishfields="__all__"# queryset或者model对象-------------》json数据ps=PublishSerializers(queryset,many=True)ps.data # [{},{},{}]
ps=PublishSerializers(model_obj,many=False)ps.data # {}# json数据-------》记录# 添加操作ps=PublishSerializers(data=request.data)if ps.is_valid():ps.save()  # create# 更新操作
ps=PublishSerializers(model_obj,data=request.data)if ps.is_valid():ps.save()  # update5 视图组件# 版本1:# Book表class BookView(APIView):def get(self,request):book_list=Book.objects.all()bs=BookModelSerializers(book_list,many=True,context={'request': request})return Response(bs.data)def post(self,request):# post请求的数据bs=BookModelSerializers(data=request.data)if bs.is_valid():print(bs.validated_data)bs.save()# create方法return Response(bs.data)else:return Response(bs.errors)class BookDetailView(APIView):def get(self,request,id):book=Book.objects.filter(pk=id).first()bs=BookModelSerializers(book,context={'request': request})return Response(bs.data)def put(self,request,id):book=Book.objects.filter(pk=id).first()bs=BookModelSerializers(book,data=request.data)if bs.is_valid():bs.save()return Response(bs.data)else:return Response(bs.errors)def delete(self,request,id):Book.objects.filter(pk=id).delete()return Response()# 版本2:mixInfrom rest_framework import mixinsfrom rest_framework import genericsclass AuthorView(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView):queryset=Author.objects.all()serializer_class =AuthorModelSerializersdef get(self,request, *args, **kwargs):return self.list(request, *args, **kwargs)def post(self,request, *args, **kwargs):return self.create(request, *args, **kwargs)class AuthorDetailView(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView):queryset = Author.objects.all()serializer_class = AuthorModelSerializersdef get(self,request,*args, **kwargs):return self.retrieve(request,*args, **kwargs)def delete(self,request,*args, **kwargs):return self.destroy(request,*args, **kwargs)def put(self,request,*args, **kwargs):return self.retrieve(request,*args, **kwargs)# 版本3:基于通用类from rest_framework import mixinsfrom rest_framework import genericsclass AuthorView(generics.ListCreateAPIView):queryset=Author.objects.all()serializer_class =AuthorModelSerializersclass AuthorDetailView(generics.RetrieveUpdateDestroyAPIView):queryset = Author.objects.all()serializer_class = AuthorModelSerializers# 版本4class AuthorModelView(viewsets.ModelViewSet):queryset = Author.objects.all()serializer_class = AuthorModelSerializersurl(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}),name="author"),url(r'^authors/(?P<pk>\d+)/$', views.AuthorModelView.as_view({"get":"retrieve","put"流程:url(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}),name="author"),url(r'^authors/$', ViewSetMixin.as_view({"get":"list","post":"create"}),name="author"),url(r'^authors/$', ViewSetMixin类下的view),一旦访问 /authors/:ViewSetMixindef  view():for method, action in actions.items(): # {"get":"list","post":"create"}handler = getattr(self, action)    # self.list  self.create
                    setattr(self, method, handler)self.dispatch(request, *args, **kwargs)APIView类下的self.dispatch# 分发if request.method.lower() in self.http_method_names:handler = getattr(self,request.method.lower(),self.http_method_not_allowed)response = handler(request, *args, **kwargs) # self.list()return response6 认证权限频率 组件request.META:{'ALLUSERSPROFILE': 'C:\\ProgramData','APPDATA': 'C:\\Users\\Administrator\\AppData\\Roaming','COMMONPROGRAMFILES': 'C:\\Program Files\\Common Files','COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files','COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files','COMPUTERNAME': 'PC201712041709','COMSPEC': 'C:\\Windows\\system32\\cmd.exe','DJANGO_SETTINGS_MODULE': 'restdemo.settings','FP_NO_HOST_CHECK': 'NO', 'HOMEDRIVE': 'C:','HOMEPATH': '\\Users\\Administrator','LOCALAPPDATA': 'C:\\Users\\Administrator\\AppData\\Local','LOGONSERVER': '\\\\PC201712041709','NUMBER_OF_PROCESSORS': '4', 'OS': 'Windows_NT','PATH': 'C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36;C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\Scripts;C:\\Python27;E:\\MySQL Server 5.6\\bin;C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\Scripts\\;C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\;C:\\Users\\Administrator\\AppData\\Local\\atom\\bin','PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC','PROCESSOR_ARCHITECTURE': 'AMD64','PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 60 Stepping 3, GenuineIntel','PROCESSOR_LEVEL': '6', 'PROCESSOR_REVISION': '3c03','PROGRAMDATA': 'C:\\ProgramData','PROGRAMFILES': 'C:\\Program Files','PROGRAMFILES(X86)': 'C:\\Program Files (x86)','PROGRAMW6432': 'C:\\Program Files','PSMODULEPATH': 'C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules\\','PUBLIC': 'C:\\Users\\Public', 'PYCHARM_HOSTED': '1', 'PYTHONIOENCODING': 'UTF-8','PYTHONPATH': 'C:\\Users\\Administrator\\PycharmProjects\\s9\\restdemo', 'PYTHONUNBUFFERED': '1','SESSIONNAME': 'Console', 'SYSTEMDRIVE': 'C:', 'SYSTEMROOT': 'C:\\Windows','TEMP': 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp', 'TMP': 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp','USERDOMAIN': 'PC201712041709','USERNAME': 'Administrator','USERPROFILE': 'C:\\Users\\Administrator','WINDIR': 'C:\\Windows', 'WINDOWS_TRACING_FLAGS': '3','WINDOWS_TRACING_LOGFILE': 'C:\\BVTBin\\Tests\\installpackage\\csilogfile.log','RUN_MAIN': 'true', 'SERVER_NAME': 'PC201712041709','GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_PORT': '8000','REMOTE_HOST': '','CONTENT_LENGTH': '','SCRIPT_NAME': '','SERVER_PROTOCOL': 'HTTP/1.1','SERVER_SOFTWARE': 'WSGIServer/0.2','REQUEST_METHOD': 'GET','PATH_INFO': '/authors/','QUERY_STRING': 'token=8204b8e3ac40bf59ae480d17c146b51a','REMOTE_ADDR': '127.0.0.1','CONTENT_TYPE': 'text/plain','HTTP_HOST': '127.0.0.1:8000','HTTP_CONNECTION': 'keep-alive','HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36','HTTP_UPGRADE_INSECURE_REQUESTS': '1','HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8','HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 'HTTP_COOKIE': 'csrftoken=jtus3l4GJEc9TFXWYCWxkBIZprcOv7C1vFMIyOHs7Zkxt015FwVZ2KEEeDV6LOyN', 'wsgi.input': <_io.BufferedReader name=832>, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 'wsgi.version': (1, 0), 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.file_wrapper': <class 'wsgiref.util.FileWrapper'>}7 解析器-----数据解析器from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParserparser_classes = [JSONParser,FormParser]8 路由控制针对:url(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}),name="author"),url(r'^authors/(?P<pk>\d+)/$', views.AuthorModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}),name="detailauthor"),class AuthorModelView(viewsets.ModelViewSet):queryset = Author.objects.all()serializer_class = AuthorModelSerializersurl(r'^books/$', views.BookModelView.as_view({"get":"list","post":"create"}),name="author"),url(r'^books/(?P<pk>\d+)/$', views.BookModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}),name="detailbook"),class AuthorModelView(viewsets.ModelViewSet):queryset = Author.objects.all()serializer_class = AuthorModelSerializers9 分页10 响应器  Response

总结 - 笔记

REST_FRAMEWORK = {# 'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth'],# 'DEFAULT_PERMISSION_CLASSES': ['app01.utils.SVIPPermission'],# 'DEFAULT_THROTTLE_CLASSES': ['app01.utils.VisitThrottle'],# "DEFAULT_THROTTLE_RATES": {#     "visit_rate": "1/m",# }# "PAGE_SIZE":2
}

settings.py

from django.conf.urls import url,include
from django.contrib import adminfrom app01 import viewsfrom rest_framework import routers
routers = routers.DefaultRouter()
routers.register("authors",views.AuthorModelView)urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^publishes/$', views.PublishView.as_view(), name="publish"),url(r'^publishes/(?P<pk>\d+)/$', views.PublishDetailView.as_view(), name="detail_publish"),url(r"^books/$", views.BookView.as_view(), name="books"),url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view(), name="detail_book"),# url(r'^authors/$',views.AuthorView.as_view(),name="author"),# url(r'^authors/(?P<pk>\d+)',views.AuthorDetailView.as_view(),name="detail_author"),# url(r'^authors/$', views.AuthorModelView.as_view({"get": "list", "post": "create"}), name="author"),# url(r'^authors/(?P<pk>\d+)',#     views.AuthorModelView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"}), name="detail_author"),
url(r'',include(routers.urls)),url(r'^login/$', views.LoginView.as_view(), name="login")]

urls.py

from .models import *
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthenticationclass TokenAuth(BaseAuthentication):def authenticate(self,request):token = request.GET.get("token")token_obj = Token.objects.filter(token=token).first()if not token_obj:raise exceptions.AuthenticationFailed("验证失败")return (token_obj.user.name, token_obj)class SVIPPermission(object):message = "只有超级用户才能访问"def has_permission(self,request,view):username = request.useruser_type = User.objects.filter(name=username).first().user_typeif user_type == 3:return Trueelse:return False# 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)<3:
#             history.insert(0,ctime)
#             return True
#         else:
#             return False
#
#     def wait(self):
#         import time
#         ctime=time.time()
#         return 60-(ctime-self.history[-1])from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):scope="visit_rate"def get_cache_key(self, request, view):return self.get_ident(request)

utils.py

from django.shortcuts import render, HttpResponsefrom django.views import View
from .models import *
import json
from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.response import Response# 为queryset,model 对象 做序列化得
# class PublishSerializers(serializers.Serializer):
#     name = serializers.CharField()
#     email = serializers.CharField()class PublishModelSerializers(serializers.ModelSerializer):class Meta:model = Publishfields = "__all__"class BookModelSerializers(serializers.ModelSerializer):class Meta:model = Bookfields = "__all__"# 显示超链接publish = serializers.HyperlinkedIdentityField(view_name='detailpublish', # 别名 含正则表达式lookup_field= 'publish_id',lookup_url_kwarg='pk')# publish = serializers.CharField(source="publish.pk")# publish = serializers.CharField()# 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)#     return temp# def create(self, validated_data):#     print('--->',validated_data)#     book = Book.objects.create(title=validated_data["title"],price=validated_data['price'],#                         pub_date=validated_data['pub_date'],publish_id=validated_data['publish']['pk'])#     book.authors.add(*validated_data['authors'])#
    #     return bookclass AuthorModelSerializers(serializers.ModelSerializer):class Meta:model = Authorfields = "__all__"

serializer.py

from django.db import models# Create your models here.class User(models.Model):name = models.CharField(max_length=32)pwd = models.CharField(max_length=32)type_choices = ((1,"普通用户"),(2,"VIP"),(3,"SVIP"))user_type = models.IntegerField(choices=type_choices,default=1)class Token(models.Model):user = models.OneToOneField("User")token = models.CharField(max_length=128)def __str__(self):return self.tokenclass 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.titleclass Publish(models.Model):name = models.CharField(max_length=32)email = models.EmailField()def __str__(self):return self.nameclass Author(models.Model):name = models.CharField(max_length=32)age = models.IntegerField()def __str__(self):return self.name

models.py

from django.shortcuts import render,HttpResponse# Create your views here.from django.views import View
from .models import *
import json
from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.response import Responsefrom app01.serializer import *class PublishView(APIView):def get(self, request):publish_list = Publish.objects.all()ret = PublishModelSerializers(publish_list, many=True)return Response(ret.data)def post(self, request):ps = PublishModelSerializers(data=request.data)if ps.is_valid():ps.save()return Response(ps.data)else:return Response(ps.errors)class PublishDetailView(APIView):def get(self, request, pk):publish = Publish.objects.filter(pk=pk).first()ps = PublishModelSerializers(publish)return Response(ps.data)def put(self, request, pk):publish = Publish.objects.filter(pk=pk).first()ps = PublishModelSerializers(publish, data=request.data)if ps.is_valid():ps.save()return Response(ps.data)else:return Response(ps.errors)def delete(self, request, pk):Publish.objects.filter(pk=pk).delete()return Response()from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParser
"""
默认得是 JSONParser FormParser  MultiPartParser
"""
# Book
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination
class MyPageNumberPagination(PageNumberPagination):page_size = 1page_query_param = "page"page_size_query_param = "size"max_page_size = 2  # 限制 size 得大小 不能超过多少!!
# # http://127.0.0.1:8000/books/?page=2&size=2class MyLimitOffsetPagination(LimitOffsetPagination):default_limit = 1# limit_query_param =
# http://127.0.0.1:8000/books/?limit=2&offset=2# 偏移class BookView(APIView):# authentication_classes = [TokenAuth]
parser_classes = [JSONParser,FormParser]def get(self,request):print("user:--->", request.user)print(request.auth)book_list = Book.objects.all()# 分页 page_size 配置 setting 全局得 单独怎么设置?  写个类# from rest_framework.pagination import PageNumberPagination# pnp = PageNumberPagination()# pnp = MyPageNumberPagination()pnp = MyLimitOffsetPagination()books_page = pnp.paginate_queryset(book_list,request,self)# bs = BookModelSerializers(book_list,many=True,context={'request': request})bs = BookModelSerializers(books_page,many=True,context={'request': request})# return HttpResponse(bs.data)return Response(bs.data)def post(self,request):print('data:--->', request.data,type(request.data))# post 请求的数据bs = BookModelSerializers(data=request.data,context={'request': request})if bs.is_valid():bs.save()  # create 方法print(bs.validated_data)return Response(bs.data)else:return Response(bs.errors)class BookDetailView(APIView):def get(self,request,id):book = Book.objects.filter(pk=id).first()# 序列化bs = BookModelSerializers(book)return Response(bs.data)def put(self,request,id):book = Book.objects.filter(pk=id).first()bs = BookModelSerializers(book,data=request.data)if bs.is_valid():bs.save()return Response(bs.data)else:return Response(bs.errors)def delete(self,request,id):Book.objects.filter(pk=id).delete()return Response()# Author
# 逻辑复用
# 三种方法#########################   mixin类编写视图  ############################### from rest_framework import mixins, generics
#
# class AuthorView(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView):
#     queryset = Author.objects.all()
#     serializer_class = AuthorModelSerializers
#
#     def get(self,request,*args,**kwargs):
#         return self.list(request,*args,**kwargs)
#
#     def post(self,request,*args,**kwargs):
#         return self.create(self, request, *args, **kwargs)
#
#
# class AuthorDetailView(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView):
#     queryset = Author.objects.all()
#     serializer_class = AuthorModelSerializers
#
#     def get(self,request,pk,*args,**kwargs):
#         return self.retrieve(request,pk,*args,**kwargs)
#
#     def delete(self,request,*args,**kwargs):
#         return self.destroy(request,*args,**kwargs)
#
#     def put(self,request,*args,**kwargs):
#         return self.update(request,*args,**kwargs)#########################   使用得通用得基于类得视图  ############################### from rest_framework import mixins, generics
#
# class AuthorView(generics.ListCreateAPIView):
#     queryset = Author.objects.all()
#     serializer_class = AuthorModelSerializers
#
#
# class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView):
#     queryset = Author.objects.all()
#     serializer_class = AuthorModelSerializers#########################   viewsets.ModelViewSet  ##############################
# url 需要是一趟线 走一个视图类
# url 中 利用参数 来指定 什么方式 用什么方法 执行
from .utils import TokenAuth,SVIPPermission
from rest_framework import viewsetsclass VisitRateThrottle(object):def allow_request(self,request,view):# 要求访问站点得频率不能超过每分钟20次if 1:# 每次来 存下来 比对一下,间隔多久 超过一分钟# IP, 请求首行(request.method request.path)#  请求头(request.meta) 请求体(request.body)print("meta:----->",request.META)print(request.META.get("REMOTE_ADDR"))  # 客户端得ip 这里面 你要保存什么  ip 时间 记录下来;# 频率 限制 实现 功能!!!return Trueelse:return Falsefrom rest_framework.response import Responseclass AuthorModelView(viewsets.ModelViewSet):# authentication_classes = [TokenAuth,]# permission_classes = [SVIPPermission,]  取配全局八# throttle_classes = [VisitRateThrottle]
queryset = Author.objects.all()serializer_class = AuthorModelSerializerspagination_class = MyPageNumberPagination# 完美!  ok# 类得继承 , 表示形式 需求 展示 数据 ,覆盖方法 单独写 类得继承 可重写 覆盖
#
#     def list(self,request,*args,**kwargs):
#         pass# ------------------------------------------------------def get_random_str(user):import hashlib,timectime=str(time.time())md5=hashlib.md5(bytes(user,encoding="utf8"))md5.update(bytes(ctime,encoding="utf8"))return md5.hexdigest()class LoginView(APIView):authentication_classes = []def post(self,request):name = request.data.get("name")pwd = request.data.get("pwd")user = User.objects.filter(name=name,pwd=pwd).first()res = {"state_code":1000,"msg":None}if user:random_str = get_random_str(user.name)token = Token.objects.update_or_create(user=user,defaults={"token":random_str})res['token'] = random_strelse:res["status_code"] = 1001 # 错误状态码res['msg'] = "用户名或密码错误"import jsonreturn Response(json.dumps(res,ensure_ascii=False))

views.py

八、渲染器、版本

配置:

1.添加配置

REST_FRAMEWORK = {'DEFAULT_RENDERER_CLASSES':['rest_framework.renderers.JSONRenderer','rest_framework.renderers.BrowsableAPIRenderer'],'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning','ALLOWED_VERSIONS': ['v1', 'v2'],  # 允许的版本'VERSION_PARAM': 'version',  # 参数'DEFAULT_VERSION': 'v1',  # 默认版本
}

2.设置路由:

luffycity/urls.py

from django.conf.urls import url,include
from django.contrib import adminurlpatterns = [# url(r'^admin/', admin.site.urls),url(r'^api/(?P<version>\w+)/', include('api.urls')),
]

api/urls.py

from django.conf.urls import url
from api.views import courseurlpatterns = [url(r'^course/$', course.CourseView.as_view()),
]

3.获取版本

request.version 获取版本  

转载于:https://www.cnblogs.com/alice-bj/p/9252207.html

Django - rest - framework - 下相关推荐

  1. 03 Django REST Framework 视图和路由

    01-DRF中的request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别 ...

  2. Django REST framework API 指南(12):验证器

    官方原文链接 本系列文章 github 地址 转载请注明出处 验证器 大多数情况下,您在 REST framework 中处理验证时,只需依赖默认的字段验证,或者在序列化类或字段类上编写明确的验证方法 ...

  3. Django REST framework的一些奇巧淫技(干货!!!)

    开始之前,假设你已经有Django和Django REST framework的一些基础了 mixins,ViewSet和routers配合使用 minxis的类有5种 CreateModelMixi ...

  4. Django REST framework快速入门

    1)简介: 接口使用REST framework,REST framework是一套基于Django 的 REST 框架,是一个强大灵活的构建 Web API 的工具包. 写接口三步完成:连接数据库. ...

  5. Django REST framework 1

    Django REST framework Django REST framework官方文档:点击  中文文档:点击 安装djangorestframework:pip3 install djang ...

  6. 在django restful framework中设置django model的property

    众所周知,在django的model中,可以某些字段设置@property和setter deleter getter,这样就可以在存入数据的时候进行一些操作,具体原理请参见廖雪峰大神的博客https ...

  7. django html5 关系,Django REST FrameWork中文教程5:关系和超链接API

    目前我们的API中的关系是用主键表示的.我们将通过使用超链接来提高我们API的内部联系. 为我们的API创建一个根路径 现在我们有'snippets'和'users'的路径,但是我们的API没有一个入 ...

  8. 源码剖析Django REST framework的认证方式及自定义认证

    源码剖析Django REST framework的认证方式 由Django的CBV模式流程,可以知道在url匹配完成后,会执行自定义的类中的as_view方法. 如果自定义的类中没有定义as_vie ...

  9. Django Rest Framework源码剖析(二)-----权限

    一.简介 在上一篇博客中已经介绍了django rest framework 对于认证的源码流程,以及实现过程,当用户经过认证之后下一步就是涉及到权限的问题.比如订单的业务只能VIP才能查看,所以这时 ...

  10. DRF (Django REST framework) 框架介绍

    Web应用模式 在开发Web应用中,有两种应用模式: 前后端不分离 前后端分离 1 前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控 ...

最新文章

  1. 电子学会青少年编程等级考试Python一级题目解析10
  2. Everest 0.6 设置ADSL上网
  3. BCH协议升级倒计时——超过68%的BCH全节点已支持升级
  4. Dropbox用户数增速恢复:突破5亿 9个月增加1亿
  5. 数学笔记--线性代数
  6. 欧拉函数(Euler_Function)
  7. java获取系统当前时间格式化_java 获取系统当前时间并格式化
  8. C#根据网址生成静态页面
  9. JavaScript学习(七十九)—值传递和地址传递
  10. backtrack常用的一些综合扫描工具实例用法
  11. nginx 过滤请求URL参数及重定向
  12. ROI和widthStep
  13. windows10连接共享打印机报错:错误 0x00000709 解决方法
  14. 2021-05-12 MongoDB面试题 应该启动一个集群分片(sharded)还是一个非集群分片的 MongoDB 环境
  15. 计算机网络学习-应用层笔记
  16. HBase与Hadoop生态其他组件的联系
  17. (看得懂的)海明码的编码和校验方法
  18. 文献笔记:RhythmNet: End-to-end Heart Rate Estimation from Face via Spatial-temporal Representation
  19. saltstack+git+rsync发布代码
  20. pyzbar报错解决方法:WARNING: .\zbar\decoder\pdf417.c:89: <unknown>:

热门文章

  1. 明显调用的表达式前的括号必须具有(指针)函数类型
  2. 游戏开发之使用类封装双链表数据结构及双链表迭代器--第二版(C++基础)
  3. C语言关于一个作用域内的局部变量反复申请同一个栈区内存空间的事儿
  4. 华为STP相关功能配置
  5. kali 安装sogou输入法(kali 版本介于16.1-18.2)
  6. uestc--758--P酱的冒险旅途
  7. POJ--3278 Catch That Cow
  8. mysql如何把一个表直接拷贝到一个新的表
  9. shell中expr强大功能(2)
  10. LinkedIn首席数据科学家谈数据分析