2018-10-30 20:25:23
终于学完了rest_framework 这个框架!
这个框架有一些基本组件!最重要的就是看源码!要一个类一个类的去找!按顺序!
并且要自己配置类的时候要先看源类里面的属性,然后覆盖原来属性!不要自定义名称!
要学习好的源码的思想和方式!封装思想要多用!
详情可以参考这个连接 https://www.cnblogs.com/yuanchenqi/articles/8719520.html 拿来主义!
主要看笔记,笔记很是重要!
越努力越幸运!永远不要高估自己!
贴上源码!有空多看看!下面开始进行 vue (前端知识) 后面该是路飞,还有flak!!有空还是得多整理博客!
只是配置好路由部分后访问url出来的页面
urls.py
from django.conf.urls import url,include from django.contrib import admin from rest_framework import routers from app01 import views routers=routers.DefaultRouter() routers.register("authors",views.AuthorModelView) urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^publishes/$', views.PublishView.as_view(),name="publish"), # View:view(request)=====APIView:dispatch() url(r'^publishes/(?P<pk>\d+)/$', views.PublishDetailView.as_view(),name="detailpublish"), # View:view(request)=====APIView:dispatch() url(r'^books/$', views.BookView.as_view(),name="books"), url(r'^books/(\d+)/$', views.BookDetailView.as_view(),name="detailbook"), #url(r'^books/(\d+)/$', View:view), # view(request) # 利用指定参数 指定 什么请求方式由哪个内部方法执行 # 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"), # url(r'', include(routers.urls)), url(r'^login/$', views.LoginView.as_view(),name="login"), ]
app01/views.py
from app01.serilizer import * from rest_framework.views import APIView # Publish表 class PublishView(APIView): def get(self, request): # restframework # 取数据 # print("request.data", request.data) # print("request.data type", type(request.data)) # print(request._request.GET) # print(request.GET) # 序列化 # 方式1: # publish_list=list(Publish.objects.all().values("name","email")) # 方式2: # from django.forms.models import model_to_dict # publish_list=Publish.objects.all() # temp=[] # for obj in publish_list: # temp.append(model_to_dict(obj)) # 方式3: # from django.core import serializers # ret=serializers.serialize("json",publish_list) # 序列组件 publish_list = Publish.objects.all() ps = PublishModelSerializers(publish_list, many=True) return Response(ps.data) def post(self, request): # 取数据 # 原生request支持的操作 # print("POST",request.POST) # print("body",request.body) # # print(request) # print(type(request)) # from django.core.handlers.wsgi import WSGIRequest # 新的request支持的操作 # print("request.data",request.data) # print("request.data type",type(request.data)) # # post请求的数据 ps = PublishModelSerializers(data=request.data) if ps.is_valid(): print(ps.validated_data) ps.save() # create方法 return Response(ps.data) else: return Response(ps.errors) # publish类继承APIView 覆盖父类方法 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 # Book表 # 引入rest_framework 分页组件 from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination # 设置一个配置类继承PageNumberPagination class MyPageNumberPagination(PageNumberPagination): page_size = 1 page_query_param = 'page' page_size_query_param = "size" max_page_size = 2 # 另外一种的偏移分页 class MyLimitOffsetPagination(LimitOffsetPagination): default_limit = 1 # Book表 class BookView(APIView): # authentication_classes = [TokenAuth,] # [TokenAuth(),] # permission_classes = [] # throttle_classes = [] parser_classes = [JSONParser, FormParser] def get(self, request): print("request.user", request.user) print("request.auth", request.auth) print("_request.body", request._request.body) print("_request.GET", request._request.GET) book_list = Book.objects.all() # 分页 pnp = MyLimitOffsetPagination() books_page = pnp.paginate_queryset(book_list, request, self) bs = BookModelSerializers(books_page, many=True, context={'request': request}) return Response(bs.data) def post(self, request): # post请求的数据 print("request.data", request.data) 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) # Book表类继承APIView 覆盖父类方法 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() # ##############################################################Author # from rest_framework import mixins # from rest_framework import 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(request, *args, **kwargs) # # # class AuthorDetailView(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView): # queryset = Author.objects.all() # serializer_class = AuthorModelSerializers # # def 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) ############################################################################## # # from rest_framework import mixins # from rest_framework import generics # # # class AuthorView(generics.ListCreateAPIView): # queryset=Author.objects.all() # serializer_class =AuthorModelSerializers # # class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView): # queryset = Author.objects.all() # serializer_class = AuthorModelSerializers ############################################################################## from rest_framework import viewsets # 频率组件 class VisitRateThrottle(object): def allow_request(self, request, view): # 要求访问站点的频率不能超过每分钟20次 if 1: print(request.META.get("REMOTE_ADDR")) return True else: return False from rest_framework.response import Response class AuthorModelView(viewsets.ModelViewSet): # authentication_classes = [TokenAuth,] # permission_classes=[SVIPPermission,] # throttle_classes = [VisitRateThrottle] # 限制某个IP每分钟访问次数不能超过20次 queryset = Author.objects.all() serializer_class = AuthorModelSerializers pagination_class = MyPageNumberPagination renderer_classes = [] # 生成一个随机token的类 def get_random_str(user): import hashlib, time ctime = str(time.time()) md5 = hashlib.md5(bytes(user, encoding="utf8")) md5.update(bytes(ctime, encoding="utf8")) return md5.hexdigest() from .models import User # 手写原生的 login视图 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_str else: res["state_code"] = 1001 # 错误状态码 res["msg"] = "用户名或者密码错误" import json return Response(json.dumps(res, ensure_ascii=False))
app01/models.py
# Create your models here. 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.token class Book(models.Model): title=models.CharField(max_length=32) price=models.IntegerField() pub_date=models.DateField() publish=models.ForeignKey("Publish") authors=models.ManyToManyField("Author") def __str__(self): return self.title class Publish(models.Model): name=models.CharField(max_length=32) email=models.EmailField() def __str__(self): return self.name class Author(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() def __str__(self): return self.name
app01/utils.py
from rest_framework import exceptions from rest_framework.authentication import BaseAuthentication from .models import * # 用于认证的类 class 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("验证失败!") else: return token_obj.user.name,token_obj.token # 用于增加权限的类 class SVIPPermission(object): message = "只有超级用户才能访问" def has_permission(self,request,view): username=request.user user_type=User.objects.filter(name=username).first().user_type if user_type==3: return True # 通过权限认证 else: return False
app01/serilizer.py
from rest_framework import serializers from app01.models import *
"""
用于序例化的一个模块
""" # 为queryset,model对象做序列化 class PublishSerializers(serializers.Serializer): name = serializers.CharField() email = serializers.CharField() # 类似于ModelForm # 这个也是做转换的 class PublishModelSerializers(serializers.ModelSerializer): class Meta: model=Publish fields="__all__" # class BookSerializers(serializers.Serializer): # title = serializers.CharField(max_length=32) # price = serializers.IntegerField() # pub_date = serializers.DateField() # 一对多 # publish=serializers.CharField(source="publish.name") # 多对多 # #authors=serializers.CharField(source="authors.all") # authors = serializers.SerializerMethodField() # 类似于钩子 # def get_authors(self,obj): # temp=[] # for obj in obj.authors.all(): # temp.append(obj.name) # return temp ''' 序列化BookSerializers(book_list,many=True)过程: temp=[] for obj in book_list: temp.append({ "title":obj.title, "price":obj.price, "pub_date":obj.pub_date, "publish":str(obj.publish), # obj.publish.name #"authors":obj.authors.all, "authors": get_authors(obj) }) ''' class BookModelSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" #publish=serializers.CharField(source="publish.pk") publish=serializers.HyperlinkedIdentityField( view_name="detailpublish", lookup_field="publish_id", lookup_url_kwarg="pk" ) # 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",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 book class AuthorModelSerializers(serializers.ModelSerializer): class Meta: model = Author fields = "__all__"
settings.py
""" Django settings for restdemo project. Generated by 'django-admin startproject' using Django 1.11.1. For more information on this file, see https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.11/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'zh7zb+r@$sgy(e=2p%dh7229g2z*diug%7ifpg$53a8=_gvi=d' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', "rest_framework", ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', #'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'restdemo.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates'),], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'restdemo.wsgi.application' # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } # Password validation # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/' # 将自己的认证类变成全局的! REST_FRAMEWORK = { # "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.TokenAuth",], # "DEFAULT_PERMISSION_CLASSES": ["app01.utils.SVIPPermission",], # "PAGE_SIZE":1 }
笔记!! 重点多看源码多看rest_framework的各个类的源码!!!!
day99 1 CBV 2 APIView class BookView(APIView):pass url(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.user self.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() raise if user_auth_tuple is not None: self._authenticator = authenticator self.user, self.auth = user_auth_tuple return # 权限组件 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 response 4 序列化组件 class PublishSerializers(serializers.Serializer): name = serializers.CharField() email = serializers.CharField() class PublishModelSerializers(serializers.ModelSerializer): class Meta: model=Publish fields="__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() # update 5 视图组件 # 版本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:mixIn from rest_framework import mixins from rest_framework import 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(request, *args, **kwargs) class AuthorDetailView(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView): queryset = Author.objects.all() serializer_class = AuthorModelSerializers def 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 mixins from rest_framework import generics class AuthorView(generics.ListCreateAPIView): queryset=Author.objects.all() serializer_class =AuthorModelSerializers class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView): queryset = Author.objects.all() serializer_class = AuthorModelSerializers # 版本4 class AuthorModelView(viewsets.ModelViewSet): queryset = Author.objects.all() serializer_class = AuthorModelSerializers 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" 流程: 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/: ViewSetMixin def 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 response 6 认证权限频率 组件 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,FileUploadParser parser_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 = AuthorModelSerializers url(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 = AuthorModelSerializers 9 分页 10 响应器 Response