Django - rest - framework - 下
一、视图三部曲
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 - 下相关推荐
- 03 Django REST Framework 视图和路由
01-DRF中的request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别 ...
- Django REST framework API 指南(12):验证器
官方原文链接 本系列文章 github 地址 转载请注明出处 验证器 大多数情况下,您在 REST framework 中处理验证时,只需依赖默认的字段验证,或者在序列化类或字段类上编写明确的验证方法 ...
- Django REST framework的一些奇巧淫技(干货!!!)
开始之前,假设你已经有Django和Django REST framework的一些基础了 mixins,ViewSet和routers配合使用 minxis的类有5种 CreateModelMixi ...
- Django REST framework快速入门
1)简介: 接口使用REST framework,REST framework是一套基于Django 的 REST 框架,是一个强大灵活的构建 Web API 的工具包. 写接口三步完成:连接数据库. ...
- Django REST framework 1
Django REST framework Django REST framework官方文档:点击 中文文档:点击 安装djangorestframework:pip3 install djang ...
- 在django restful framework中设置django model的property
众所周知,在django的model中,可以某些字段设置@property和setter deleter getter,这样就可以在存入数据的时候进行一些操作,具体原理请参见廖雪峰大神的博客https ...
- django html5 关系,Django REST FrameWork中文教程5:关系和超链接API
目前我们的API中的关系是用主键表示的.我们将通过使用超链接来提高我们API的内部联系. 为我们的API创建一个根路径 现在我们有'snippets'和'users'的路径,但是我们的API没有一个入 ...
- 源码剖析Django REST framework的认证方式及自定义认证
源码剖析Django REST framework的认证方式 由Django的CBV模式流程,可以知道在url匹配完成后,会执行自定义的类中的as_view方法. 如果自定义的类中没有定义as_vie ...
- Django Rest Framework源码剖析(二)-----权限
一.简介 在上一篇博客中已经介绍了django rest framework 对于认证的源码流程,以及实现过程,当用户经过认证之后下一步就是涉及到权限的问题.比如订单的业务只能VIP才能查看,所以这时 ...
- DRF (Django REST framework) 框架介绍
Web应用模式 在开发Web应用中,有两种应用模式: 前后端不分离 前后端分离 1 前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控 ...
最新文章
- 电子学会青少年编程等级考试Python一级题目解析10
- Everest 0.6 设置ADSL上网
- BCH协议升级倒计时——超过68%的BCH全节点已支持升级
- Dropbox用户数增速恢复:突破5亿 9个月增加1亿
- 数学笔记--线性代数
- 欧拉函数(Euler_Function)
- java获取系统当前时间格式化_java 获取系统当前时间并格式化
- C#根据网址生成静态页面
- JavaScript学习(七十九)—值传递和地址传递
- backtrack常用的一些综合扫描工具实例用法
- nginx 过滤请求URL参数及重定向
- ROI和widthStep
- windows10连接共享打印机报错:错误 0x00000709 解决方法
- 2021-05-12 MongoDB面试题 应该启动一个集群分片(sharded)还是一个非集群分片的 MongoDB 环境
- 计算机网络学习-应用层笔记
- HBase与Hadoop生态其他组件的联系
- (看得懂的)海明码的编码和校验方法
- 文献笔记:RhythmNet: End-to-end Heart Rate Estimation from Face via Spatial-temporal Representation
- saltstack+git+rsync发布代码
- pyzbar报错解决方法:WARNING: .\zbar\decoder\pdf417.c:89: <unknown>: