当前位置: 首页 > news >正文

临沂市建设局官方网站触摸屏网站建设

临沂市建设局官方网站,触摸屏网站建设,外贸流程中的单证有哪些,室内设计培训学费Django-rest Framework 1. FBV CBV 1.1 开发模式 普通开发方式#xff08;前后端放在一起写#xff09;前后端分离 1.2 后端开发 为前端提供URL#xff08;API/接口的开发#xff09; 注#xff1a;永远返回HttpResponse 1.3 Django FBV、CBV # FBV(function base …Django-rest Framework 1. FBV CBV 1.1 开发模式 普通开发方式前后端放在一起写前后端分离 1.2 后端开发 为前端提供URLAPI/接口的开发 注永远返回HttpResponse 1.3 Django FBV、CBV # FBV(function base view)def users(request):user_list [alex,oldboy]return HttpResponse(json.dumps((user_list)))# CBV(class base view) # 路由url(r^students/, views.StudentsView.as_view()),# 视图from django.views import Viewclass StudentsView(View):def get(self,request,*args,**kwargs):return HttpResponse(GET)def post(self, request, *args, **kwargs):return HttpResponse(POST)def put(self, request, *args, **kwargs):return HttpResponse(PUT)def delete(self, request, *args, **kwargs):return HttpResponse(DELETE)1.3.1 CBV详解 CBV基于反射实现根据请求方式不同执行不同的方法。 原理 ​ url - view方法 - dispatch方法反射执行其他GET/POST/DELETE/PUT 流程 class StudentsView(View):def dispatch(self, request, *args, **kwargs):print(before)ret super(StudentsView,self).dispatch(request, *args, **kwargs)print(after)return ret def get(self,request,*args,**kwargs):return HttpResponse(GET)def post(self, request, *args, **kwargs):return HttpResponse(POST)def put(self, request, *args, **kwargs):return HttpResponse(PUT)def delete(self, request, *args, **kwargs):return HttpResponse(DELETE)【扩展】 super()方法 super 是用来解决多重继承问题的直接用类名调用父类方法在使用单继承的时候没问题但是如果使用多继承会涉及到查找顺序MRO、重复调用钻石继承等种种问题。总之前人留下的经验就是保持一致性。要不全部用类名调用父类要不就全部用 super不要一半一半 1.3.1 回顾Django中间件 中间件顾名思义是介于request与response处理之间的一道处理过程相对比较轻量级并且在全局上改变django的输入与输出 中间件流程图 # 重要的四个方法process_request(self, request)process_view(self, request, view, *args, **kwargs)process_exception(self, request, exception)process_response(self, request, response) # 模板处理的方法process_template_response使用中间件做过什么 - 权限 做IP访问频率限制 某些IP访问服务器的频率过高进行拦截比如限制每分钟不能超过20次。 用户登录认证django的csrf是如何实现 process_view方法 - 检查视图是否被 csrf_exempt 免除csrf_token认证 - 去请求体或cookie中获取token FBVcsrf_token认证情况 情况一所有函数都要认证某一个不需要认证 (csrf_exempt) MIDDLEWARE [django.middleware.security.SecurityMiddleware,django.contrib.sessions.middleware.SessionMiddleware,django.middleware.common.CommonMiddleware,django.middleware.csrf.CsrfViewMiddleware, # 全站使用csrf认证django.contrib.auth.middleware.AuthenticationMiddleware,django.contrib.messages.middleware.MessageMiddleware,django.middleware.clickjacking.XFrameOptionsMiddleware, ] from django.views.decorators.csrf import csrf_exemptcsrf_exempt # 该函数无需认证 def users(request):user_list [tom,jeck]return HttpResponse(json.dumps((user_list)))情况二所有都不认证某个函数需要认证(csrf_protect) MIDDLEWARE [django.middleware.security.SecurityMiddleware,django.contrib.sessions.middleware.SessionMiddleware,django.middleware.common.CommonMiddleware,#django.middleware.csrf.CsrfViewMiddleware, # 全站不使用csrf认证django.contrib.auth.middleware.AuthenticationMiddleware,django.contrib.messages.middleware.MessageMiddleware,django.middleware.clickjacking.XFrameOptionsMiddleware, ]from django.views.decorators.csrf import csrf_exemptcsrf_protect # 该函数需认证 def users(request):user_list [tom,jeck]return HttpResponse(json.dumps((user_list)))CBV,csrf_token认证时需要使用 method_decorator(csrf_exempt)在dispatch方法中单独方法无效 # 方式一 from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decoratorclass StudentsView(View):method_decorator(csrf_exempt)def dispatch(self, request, *args, **kwargs):return super(StudentsView,self).dispatch(request, *args, **kwargs)def get(self,request,*args,**kwargs):print(get方法)return HttpResponse(GET)def post(self, request, *args, **kwargs):return HttpResponse(POST)def put(self, request, *args, **kwargs):return HttpResponse(PUT)def delete(self, request, *args, **kwargs):return HttpResponse(DELETE)# 方式二 from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decoratormethod_decorator(csrf_exempt,namedispatch) class StudentsView(View):def get(self,request,*args,**kwargs):print(get方法)return HttpResponse(GET)def post(self, request, *args, **kwargs):return HttpResponse(POST)def put(self, request, *args, **kwargs):return HttpResponse(PUT)def delete(self, request, *args, **kwargs):return HttpResponse(DELETE)2. restful设计规范 什么是RESTful REST与技术无关代表的是一种软件架构风格REST是Representational State Transfer的简称中文翻译为“表征状态转移”REST从资源的角度类审视整个网络它将分布在网络中某个节点的资源通过URL进行标识客户端应用通过URL来获取资源的表征获得这些表征致使这些应用转变状态REST与技术无关代表的是一种软件架构风格REST是Representational State Transfer的简称中文翻译为“表征状态转移”所有的数据不过是通过网络获取的还是操作增删改查的数据都是资源将一切数据视为资源是REST区别与其他架构风格的最本质属性对于REST这种面向资源的架构风格有人提出一种全新的结构理念即面向资源架构ROAResource Oriented Architecture RESTful主要是面向资源(视网络上任何东西都是资源)设计它的接口的, 它有四个规范:- 每个资源都存在唯一的标识URI- 每个资源都具有四个动作谓词, 分别是GET/POST/PUT/DELETE- 每次的动作都是无状态的, 即是HTTP的短连接(Connection: close|keep-alive)- 交互的资源数据类型一般是json或xml.3. DRF 框架 安装 pip3 install djangorestframework3.1 基本流程 url.py from django.urls import path, include from web.views.api import TestViewurlpatterns [path(test/, TestView.as_view), ]views.py from rest_framework.views import APIView from rest_framework.response import Responseclass TestView(APIView):def dispatch(self, request, *args, **kwargs):请求到来之后都要执行dispatch方法dispatch方法根据请求方式不同触发 get/post/put等方法注意APIView中的dispatch方法有好多好多的功能return super().dispatch(request, *args, **kwargs)def get(self, request, *args, **kwargs):return Response(GET请求响应内容)def post(self, request, *args, **kwargs):return Response(POST请求响应内容)def put(self, request, *args, **kwargs):return Response(PUT请求响应内容)3.2 认证/权限 局部全局设置 3.2.1 源码 ...def dispatch(self, request, *args, **kwargs):.dispatch() is pretty much the same as Djangos regular dispatch,but with extra hooks for startup, finalize, and exception handling.self.args argsself.kwargs kwargs# 对原生request进行加工# Request(# request,# parsersself.get_parsers(),# authenticatorsself.get_authenticators(),# negotiatorself.get_content_negotiator(),# parser_contextparser_context )# request(原生的request, [BasicAuthentication对象,]) \# 获取原生request, 用request._request# 获取认证类的对象, request.authentications# 1.封装requestrequest self.initialize_request(request, *args, **kwargs)self.request requestself.headers self.default_response_headers # deprecate?try:# 2.认证self.initial(request, *args, **kwargs)# Get the appropriate handler methodif request.method.lower() in self.http_method_names:handler getattr(self, request.method.lower(),self.http_method_not_allowed)else:handler self.http_method_not_allowedresponse handler(request, *args, **kwargs)except Exception as exc:response self.handle_exception(exc)self.response self.finalize_response(request, response, *args, **kwargs)return self.response def initial(self, request, *args, **kwargs):Runs anything that needs to occur prior to calling the method handler.self.format_kwarg self.get_format_suffix(**kwargs)# Perform content negotiation and store the accepted info on the requestneg self.perform_content_negotiation(request)request.accepted_renderer, request.accepted_media_type neg# Determine the API version, if versioning is in use.version, scheme self.determine_version(request, *args, **kwargs)request.version, request.versioning_scheme version, scheme# Ensure that the incoming request is permitted# 3.实现认证self.perform_authentication(request)# 4.权限判断self.check_permissions(request)# 5.访问频率self.check_throttles(request)3.2.1.1 实现认证 def perform_authentication(self, request):Perform authentication on the incoming request.Note that if you override this and simply pass, then authenticationwill instead be performed lazily, the first time eitherrequest.user or request.auth is accessed.request.userpropertydef user(self):Returns the user associated with the current request, as authenticatedby the authentication classes provided to the request.if not hasattr(self, _user):with wrap_attributeerrors():# 获取认证对象进行一步步认证self._authenticate()return self._userdef _authenticate(self):Attempt to authenticate the request using each authentication instancein turn.# 循环认证对象[BasicAuthentication对象,]for authenticator in self.authenticators:try:# 执行认证类的authenticate方法# ① 如果authenticate方法抛出异常self._not_authenticated()执行# ② 有返回值必须是元组(self.user, self.auth)# ③ 返回None我不管下一个认证user_auth_tuple authenticator.authenticate(self)except exceptions.APIException:self._not_authenticated()raise # 没通过认证触发异常if user_auth_tuple is not None:self._authenticator authenticatorself.user, self.auth user_auth_tuplereturnself._not_authenticated()def _not_authenticated(self):Set authenticator, user authtoken representing an unauthenticated request.Defaults are None, AnonymousUser None.self._authenticator Noneif api_settings.UNAUTHENTICATED_USER:self.user api_settings.UNAUTHENTICATED_USER() # AnonymousUser 设置默认值表示匿名用户else:self.user Noneif api_settings.UNAUTHENTICATED_TOKEN:self.auth api_settings.UNAUTHENTICATED_TOKEN() # Noneelse:self.auth None3.2.1.2 权限判断 def check_permissions(self, request):Check if the request should be permitted.Raises an appropriate exception if the request is not permitted.# 遍历[权限类的对象权限类的对象]for permission in self.get_permissions():if not permission.has_permission(request, self):self.permission_denied(request,messagegetattr(permission, message, None),codegetattr(permission, code, None))权限类对象 def get_permissions(self):Instantiates and returns the list of permissions that this view requires.return [permission() for permission in self.permission_classes] # 列表生成式如果上面permission.has_permission(request, self): 为False def permission_denied(self, request, messageNone, codeNone):If request is not permitted, determine what kind of exception to raise.if request.authenticators and not request.successful_authenticator:raise exceptions.NotAuthenticated()raise exceptions.PermissionDenied(detailmessage, codecode) # 抛出异常 表示权限验证失败3.2.1.3 访问频率 def check_throttles(self, request):Check if request should be throttled.Raises an appropriate exception if the request is throttled.throttle_durations []for throttle in self.get_throttles():if not throttle.allow_request(request, self):throttle_durations.append(throttle.wait())if throttle_durations:# Filter out None values which may happen in case of config / rate# changes, see #1438durations [duration for duration in throttle_durationsif duration is not None]duration max(durations, defaultNone)self.throttled(request, duration)def get_throttles(self):Instantiates and returns the list of throttles that this view uses.return [throttle() for throttle in self.throttle_classes]3.2.2 认证使用 from django.views import View from rest_framework.views import APIView from rest_framework.authentication import BasicAuthentication from rest_framework import exceptions from rest_framework.request import Requestclass MyAuthentication(object):def authenticate(self,request):token request._request.GET.get(token)# 获取用户名和密码去数据校验if not token:raise exceptions.AuthenticationFailed(用户认证失败)return (zhb,None)def authenticate_header(self,val):passclass DogView(APIView):authentication_classes [MyAuthentication,]def get(self,request,*args,**kwargs):print(request)print(request.user) # 拿到上面authenticate方法返回值元组里的第一个元素zhb# self.dispatch # 源码流程入口ret {code:1000,msg:xxx}return HttpResponse(json.dumps(ret),status201)def post(self,request,*args,**kwargs):return HttpResponse(创建Dog)def put(self,request,*args,**kwargs):return HttpResponse(更新Dog)def delete(self,request,*args,**kwargs):return HttpResponse(删除Dog)3.2.3 全局配置(示例代码) urls.py文件 from django.conf.urls import url from django.contrib import admin from api import viewsurlpatterns [url(r^admin/, admin.site.urls),url(r^api/v1/auth/$, views.AuthView.as_view()),url(r^api/v1/order/$, views.OrderView.as_view()),url(r^api/v1/info/$, views.UserInfoView.as_view()), ]model.py文件 (创建两张表) from django.db import modelsclass UserInfo(models.Model):user_type_choices ((1,普通用户),(2,VIP),(3,SVIP),)user_type models.IntegerField(choicesuser_type_choices)username models.CharField(max_length32,uniqueTrue)password models.CharField(max_length64)class UserToken(models.Model):user models.OneToOneField(toUserInfo)token models.CharField(max_length64)settings.py 文件里面全局设置认证视图里面则不需要设置 REST_FRAMEWORK {# 全局使用的认证类DEFAULT_AUTHENTICATION_CLASSES:[api.utils.auth.FirstAuthtication,api.utils.auth.Authtication, ],# DEFAULT_AUTHENTICATION_CLASSES:[api.utils.auth.FirstAuthtication, ],# UNAUTHENTICATED_USER:lambda :匿名用户UNAUTHENTICATED_USER:None, # 匿名request.user NoneUNAUTHENTICATED_TOKEN:None,# 匿名request.auth NoneDEFAULT_PERMISSION_CLASSES:[api.utils.permission.SVIPPermission], # 权限判断全局设置DEFAULT_THROTTLE_CLASSES:[api.utils.throttle.UserThrottle],DEFAULT_THROTTLE_RATES:{Luffy:3/m, # 匿名用户每分钟3次LuffyUser:10/m, # 登录用户没分中10次} }api–views.py from django.shortcuts import render,HttpResponse from django.http import JsonResponse from rest_framework.views import APIView from rest_framework.request import Request from rest_framework import exceptions from rest_framework.authentication import BasicAuthentication from api.utils.permission import SVIPPermission from api.utils.permission import MyPermission1 from api.utils.throttle import VisitThrottle from api import modelsORDER_DICT {1:{name: 媳妇,age:18,gender:男,content:...},2:{name: 老狗,age:19,gender:男,content:...。。}, }def md5(user):import hashlibimport timectime str(time.time())m hashlib.md5(bytes(user,encodingutf-8))m.update(bytes(ctime,encodingutf-8))return m.hexdigest()class AuthView(APIView):用于用户登录认证authentication_classes [] # 全局设置了,这里设置空列表表示此处不需要认证permission_classes []throttle_classes [VisitThrottle,]def post(self,request,*args,**kwargs):ret {code:1000,msg:None}try:user request._request.POST.get(username)pwd request._request.POST.get(password)obj models.UserInfo.objects.filter(usernameuser,passwordpwd).first()if not obj:ret[code] 1001ret[msg] 用户名或密码错误# 为登录用户创建tokentoken md5(user)# 存在就更新不存在就创建models.UserToken.objects.update_or_create(userobj,defaults{token:token})ret[token] tokenexcept Exception as e:ret[code] 1002ret[msg] 请求异常return JsonResponse(ret)class OrderView(APIView):订单相关业务(只有SVIP用户有权限)def get(self,request,*args,**kwargs):# request.user# request.authself.dispatchret {code:1000,msg:None,data:None}try:ret[data] ORDER_DICTexcept Exception as e:passreturn JsonResponse(ret)class UserInfoView(APIView):订单相关业务普通用户、VIPpermission_classes [MyPermission1, ]def get(self,request,*args,**kwargs):return HttpResponse(用户信息)3.2.3.1 auth 认证 api -- utils -- auth.py 将认证类抽取出来 from rest_framework import exceptions from api import models from rest_framework.authentication import BaseAuthenticationclass FirstAuthtication(BaseAuthentication):def authenticate(self,request):passdef authenticate_header(self, request):passclass Authtication(BaseAuthentication):def authenticate(self,request):token request._request.GET.get(token)token_obj models.UserToken.objects.filter(tokentoken).first()if not token_obj:raise exceptions.AuthenticationFailed(用户认证失败)# 在rest framework内部会将整个两个字段赋值给request以供后续操作使用return (token_obj.user, token_obj)def authenticate_header(self, request):return Basic realmapi3.2.3.2 认证小结 a. 问题有些API需要用户登录成功之后才能访问有些无需登录就能访问。 b. 基本使用认证组件解决1. 创建两张表2. 用户登录返回token并保存到数据库 c. 认证流程原理- 上面源码d. 再看一遍源码1. 局部视图使用全局使用2. 匿名是request.user Nonee. 内置认证类1. 认证类必须继承from rest_framework.authentication import BaseAuthentication2. 其他认证类BasicAuthentication梳理 1. 使用 - 创建类:继承BaseAuthentication 实现authenticate方法- 返回值- None,我不管了下一认证来执行。- raise exceptions.AuthenticationFailed(用户认证失败) # from rest_framework import exceptions- (元素1元素2) # 元素1赋值给request.user; 元素2赋值给request.auth - 局部使用from rest_framework.authentication import BaseAuthentication,BasicAuthenticationclass UserInfoView(APIView):订单相关业务authentication_classes [BasicAuthentication,]def get(self,request,*args,**kwargs):print(request.user)return HttpResponse(用户信息)- 全局使用REST_FRAMEWORK {# 全局使用的认证类DEFAULT_AUTHENTICATION_CLASSES:[api.utils.auth.FirstAuthtication,api.utils.auth.Authtication, ],# UNAUTHENTICATED_USER:lambda :匿名用户UNAUTHENTICATED_USER:None, # 匿名request.user NoneUNAUTHENTICATED_TOKEN:None,# 匿名request.auth None} 2. 源码流程- dispatch- 封装request- 获取定义的认证类全局/局部通过列表生成时创建对象。- initial- perform_authenticationrequest.user(内部循环....)3.2.4 权限 api -- utils -- permission.py 将权限判断类抽取出来 from rest_framework.permissions import BasePermissionclass SVIPPermission(BasePermission): # 继承BasePermission(内置类方法)message 必须是SVIP才能访问def has_permission(self,request,view):if request.user.user_type ! 3:return Falsereturn Trueclass MyPermission1(BasePermission):def has_permission(self,request,view):if request.user.user_type 3:return Falsereturn True3.2.5 权限小结 1. 使用- 类必须继承BasePermission必须实现has_permission方法from rest_framework.permissions import BasePermissionclass SVIPPermission(BasePermission):message 必须是SVIP才能访问def has_permission(self,request,view):if request.user.user_type ! 3:return Falsereturn True- 返回值 - True, 有权访问- False无权访问- 局部 class UserInfoView(APIView):订单相关业务普通用户、VIPpermission_classes [MyPermission1, ]def get(self,request,*args,**kwargs):return HttpResponse(用户信息)- 全局 REST_FRAMEWORK {DEFAULT_PERMISSION_CLASSES:[api.utils.permission.SVIPPermission]}2. 源码流程 ...3.2.6 访问频率(节流) api -- utils -- throttle.py 将访问频率类抽取出来 自己实现 import time VISIT_RECORD {} class VisitThrottle(BaseThrottle):60S内只能访问3次def __init__(self):self.history Nonedef allow_request(self,request,view):# 1. 获取用户IPremote_addr self.get_ident(request)# 获取当前时间ctime time.time()if remote_addr not in VISIT_RECORD:VISIT_RECORD[remote_addr] [ctime,]return Truehistory VISIT_RECORD.get(remote_addr)self.history history# 当前IP对应的列表中的最后一个时间记录当前时间减60秒即60S前的时间删除while history and history[-1] ctime - 60:history.pop()# 判断当前IP对应的列表中个数3个则把当前时间插入列表if len(history) 3:history.insert(0,ctime)return True# return True # 表示可以继续访问# return False # 表示访问频率太高被限制def wait(self):# 还需要等多少秒才能访问ctime time.time()return 60 - (ctime - self.history[-1])使用Django内置类 from rest_framework.throttling import BaseThrottle,SimpleRateThrottle class VisitThrottle(SimpleRateThrottle):scope Luffydef get_cache_key(self, request, view):return self.get_ident(request)class UserThrottle(SimpleRateThrottle):scope LuffyUserdef get_cache_key(self, request, view):return request.user.usernameSimpleRateThrottle 类里面实现的方法源码 主要是allow_request() wait()方法 class SimpleRateThrottle(BaseThrottle):A simple cache implementation, that only requires .get_cache_key()to be overridden.The rate (requests / seconds) is set by a rate attribute on the Viewclass. The attribute is a string of the form number_of_requests/period.Period should be one of: (s, sec, m, min, h, hour, d, day)Previous request information used for throttling is stored in the cache.cache default_cachetimer time.timecache_format throttle_%(scope)s_%(ident)sscope NoneTHROTTLE_RATES api_settings.DEFAULT_THROTTLE_RATESdef __init__(self):if not getattr(self, rate, None):self.rate self.get_rate()self.num_requests, self.duration self.parse_rate(self.rate)def get_cache_key(self, request, view):Should return a unique cache-key which can be used for throttling.Must be overridden.May return None if the request should not be throttled.raise NotImplementedError(.get_cache_key() must be overridden)def get_rate(self):Determine the string representation of the allowed request rate.if not getattr(self, scope, None):msg (You must set either .scope or .rate for %s throttle %self.__class__.__name__)raise ImproperlyConfigured(msg)try:return self.THROTTLE_RATES[self.scope]except KeyError:msg No default throttle rate set for %s scope % self.scoperaise ImproperlyConfigured(msg)def parse_rate(self, rate):Given the request rate string, return a two tuple of:allowed number of requests, period of time in secondsif rate is None:return (None, None)num, period rate.split(/)num_requests int(num)duration {s: 1, m: 60, h: 3600, d: 86400}[period[0]]return (num_requests, duration)def allow_request(self, request, view):Implement the check to see if the request should be throttled.On success calls throttle_success.On failure calls throttle_failure.if self.rate is None:return Trueself.key self.get_cache_key(request, view)if self.key is None:return Trueself.history self.cache.get(self.key, [])self.now self.timer()# Drop any requests from the history which have now passed the# throttle durationwhile self.history and self.history[-1] self.now - self.duration:self.history.pop()if len(self.history) self.num_requests:return self.throttle_failure()return self.throttle_success()def throttle_success(self):Inserts the current requests timestamp along with the keyinto the cache.self.history.insert(0, self.now)self.cache.set(self.key, self.history, self.duration)return Truedef throttle_failure(self):Called when a request to the API has failed due to throttling.return Falsedef wait(self):Returns the recommended next request time in seconds.if self.history:remaining_duration self.duration - (self.now - self.history[-1])else:remaining_duration self.durationavailable_requests self.num_requests - len(self.history) 1if available_requests 0:return Nonereturn remaining_duration / float(available_requests) DRF (django rest framework) 补充 DRF是django第三方组件能帮助我们快速实现遵循rest ful 规范的接口。 本质是一个Django的组件app; 帮助我们快速实现遵循rest ful 规范的接口;- 帮助我们做了csrf的豁免- 页面渲染将json放到页面了- 序列化直接对QuerySet对象序列化- request.data 拿到用户数据并反序列化# 安装 pip install djangorestframework使用drf开始restful API : 1. 在app中注册drf组件 在settings的app中注册: INSTALLED_APPS [django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.messages,django.contrib.staticfiles,rest_framework ]2. 序列化 直接对QuerySet对象序列化 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7cLfX6qA-1610934599975)(C:\Users\zhanghaibo04\AppData\Roaming\Typora\typora-user-images\image-20210113154607228.png)] 【扩展】视图继承的类: APIView: 没有提供增删改查功能全部需要自己写。 ModelViewSet: 内部实现了增删改查无需自己写。url.py [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eA50QCb6-1610934599977)(C:\Users\zhanghaibo04\AppData\Roaming\Typora\typora-user-images\image-20210113162942561.png)] view.py 视图函数实现也需要 定义上面的实例化类 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9xjfQK2j-1610934599978)(C:\Users\zhanghaibo04\AppData\Roaming\Typora\typora-user-images\image-20210113162825955.png)] 3. drf 版本控制 3.1 局部控制 局部控制只能某个接口能获取到值 路由 urlpatterns [url(r^admin/, admin.site.urls),url(r^api/(?Pversion\w)/, include(api.urls)), # api/ 后设置版本 ]urlpatterns [url(r^order/$, views.OrderView.as_view()), ]导入模块及视图函数: from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.versioning import QueryParameterVersioning,URLPathVersioning # 导入版本模块class OrderView(APIView):# 原本 versioning_classNone此处重写versioning_classversioning_class URLPathVersioning def get(self,request,*args,**kwargs):print(request.version) # request.version获取版本return Response(...)3.2 全局控制 全局控制多有接口都能能获取到值 在settings.py中配置如下REST_FRAMEWORK代码 REST_FRAMEWORK {DEFAULT_VERSIONING_CLASS: rest_framework.versioning.URLPathVersioning }urlpatterns [url(r^admin/, admin.site.urls),url(r^api/(?Pversion\w)/, include(api.urls)), ]urlpatterns [url(r^order/$, views.OrderView.as_view()), ]from rest_framework.views import APIView from rest_framework.response import Response class OrderView(APIView):def get(self,request,*args,**kwargs):print(request.version)return Response(...)4. 视图 视图继承类的三种情况 直接继承APIView适用于非ORM简单操作即不操作数据库需要自定义功能时使用。 from rest_framework.views import APIViewclass TestView(APIView):def get(self,request,*args,**kwargs):pass继承ListAPIView,DestroyAPIView,UpdateAPIView,RetrieveAPIViewCreateAPIView项目中只要实现某几个接口时而不是增删改查。 from api import models from rest_framework import serializers from rest_framework.generics import ListAPIView,DestroyAPIView,UpdateAPIView,RetrieveAPIView,CreateAPIView class CourseSerializers(serializers.ModelSerializer):class Meta:model models.Coursefields __all__class CourseView(ListAPIView,CreateAPIView): # 只实现增加功能queryset models.Course.objects.all()serializer_class CourseSerializers继承ModelViewSet功能中需要实现对表的增删改查时。 from rest_framework import serializers from rest_framework.viewsets import ModelViewSetclass CourseSerializers(serializers.ModelSerializer):class Meta:model models.Coursefields __all__class CourseView(ModelViewSet):queryset models.Course.objects.all()serializer_class CourseSerializers面试题GenericAPIView的作用 指定了接口执行的流程。如果继承了GenericAPIView的类他们的在内部取数据时调用 self.get_queryset()它定义在GenericAPIView它内部返回self.queryset5. 案例 5.1 zhb项目 创建zhb项目5 张表 from django.db import modelsclass Tag(models.Model):标签表caption models.CharField(verbose_name标签名称,max_length32)class Course(models.Model):课程表例如:Linux、Python、测试课程title models.CharField(verbose_name课程名称,max_length32)class Module(models.Model):模块表name models.CharField(verbose_name模块名,max_length32)course models.ForeignKey(verbose_name课程, toCourse, on_deletemodels.CASCADE)class Video(models.Model):视频表title models.CharField(verbose_name视频名称, max_length32)vid models.CharField(verbose_namexxx视频ID, max_length64)tag models.ManyToManyField(verbose_name标签,toTag,)5.2 第一个接口 实现接口返回一个字符串含有版本 # settings 中注册 INSTALLED_APPS [django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.messages,django.contrib.staticfiles,api.apps.ApiConfig,rest_framework, ]# settings中配置版本 REST_FRAMEWORK {DEFAULT_VERSIONING_CLASS: rest_framework.versioning.URLPathVersioning,ALLOWED_VERSIONS: [v1, v2] # 允许版本 }urlpatterns [path(admin/, admin.site.urls),re_path(api/(?Pversion\w)/test/, views.TestView.as_view()), ]from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.versioning import URLPathVersioningclass TestView(APIView):def get(self, request, *args, **kwargs):print(request.version)return Response(成功)5.3 第二个接口 访问接口时返回一个XML文件 cross-domain-policy allow-access-from domain*.polyv.net/ /cross-domain-policyurlpatterns [path(admin/, admin.site.urls),re_path(api/(?Pversion\w)/test/, views.TestView.as_view()),re_path(api/(?Pversion\w)/crossdomain/, views.CrossView.as_view()), ]class CrossView(APIView):def get(self, request, *args, **kwargs):with open(crossdomain.xml) as f:data f.read()return Response(data)5.4 基于APIView 实现对课程表的 获取所有的数据 增加数据 urlpatterns [path(admin/, admin.site.urls),re_path(api/(?Pversion\w)/test/, views.TestView.as_view()),re_path(api/(?Pversion\w)/cross/, views.CrossView.as_view()),re_path(api/(?Pversion\w)/course/, views.CourseView.as_view()), ]# 新建ser.py 用作新建序列化类 from api import models from rest_framework import serializersclass CourseSerializer(serializers.ModelSerializer):class Meta:model models.Coursefields __all__# view函数 from api import models from api.ser import CourseSerializer from rest_framework.views import APIView from rest_framework.response import Responseclass CourseView(APIView):def get(self, request, *args, **kwargs):result {status:1000, data:None, error:None}queryset models.Course.objects.all()ser CourseSerializer(instancequeryset, manyTrue)result[data] ser.datareturn Response(result)def post(self, request, *args, **kwargs):# 1.获取用户提交的数据 request.data# 2.校验数据的合法性 序列化# 3.校验通过save# 4.不通过报错result {status:1000, data:None, error:None}ser CourseSerializer(datarequest.data)if ser.is_valid():ser.save()return Response(result)result[error] ser.errorsresult[status] 2000return Response(result)5.5 基于ListAPIViewCreateAPIView 实现5.4功能 urlpatterns [path(admin/, admin.site.urls),re_path(api/(?Pversion\w)/test/, views.TestView.as_view()),re_path(api/(?Pversion\w)/cross/, views.CrossView.as_view()),re_path(api/(?Pversion\w)/course/$, views.CourseView.as_view()),re_path(api/(?Pversion\w)/course/new/$, views.CourseNewView.as_view()), ]from api import models from api.ser import CourseSerializer from rest_framework.response import Response from rest_framework.generics import ListAPIView, CreateAPIViewclass CourseNewView(ListAPIView,CreateAPIView):queryset models.Course.objects.all()serializer_class CourseSerializer5.6 对Course表实现增删改查 urlpatterns [path(admin/, admin.site.urls),re_path(api/(?Pversion\w)/test/, views.TestView.as_view()),re_path(api/(?Pversion\w)/cross/, views.CrossView.as_view()),re_path(api/(?Pversion\w)/course/$, views.CourseView.as_view()),re_path(api/(?Pversion\w)/course/new/$, views.CourseNewView.as_view()),re_path(api/(?Pversion\w)/course/curd/$, views.CourseCurdView.as_view({get: list, post: create})),re_path(api/(?Pversion\w)/course/curd/(?Ppk\d)/$, views.CourseCurdView.as_view({get:retrieve,put:update,delete:destroy,patch:partial_update})), ]from api import models from api.ser import CourseSerializer from rest_framework.response import Response from rest_framework.viewsets import ModelViewSetclass CourseCurdView(ModelViewSet):queryset models.Course.objects.all()serializer_class CourseSerializer5.7 对5.6的功能改变 对Course表实现增删改查对列表页面的功能不要再去数据库获取而去文件中获取即可 urlpatterns [path(admin/, admin.site.urls),re_path(api/(?Pversion\w)/test/, views.TestView.as_view()),re_path(api/(?Pversion\w)/cross/, views.CrossView.as_view()),re_path(api/(?Pversion\w)/course/$, views.CourseView.as_view()),re_path(api/(?Pversion\w)/course/new/$, views.CourseNewView.as_view()),re_path(api/(?Pversion\w)/course/curd/$, views.CourseCurdView.as_view({get: list, post: create})),re_path(api/(?Pversion\w)/course/curd/(?Ppk\d)/$, views.CourseCurdView.as_view({get:retrieve,put:update,delete:destroy,patch:partial_update})),re_path(api/(?Pversion\w)/course/file/$, views.CourseFileView.as_view({get: list, post: create})),re_path(api/(?Pversion\w)/course/file/(?Ppk\d)/$, views.CourseFileView.as_view({get:retrieve,put:update,delete:destroy,patch:partial_update})), class CourseFileView(ModelViewSet):queryset models.Course.objects.all()serializer_class CourseSerializer# 重写list方法改变原有的功能def list(self, request, *args, **kwargs):with open(crossdomain.xml) as f:data f.read()return Response(data)5.8 获取列表数据 基于APIView serializer实现对模块表 实现获取数据 【ForeignKey】 显示所有数据 class ModuleSerializer(serializers.ModelSerializer):class Meta:model models.Modulefields __all__class ModuleView(APIView):def get(self, request, *args, **kwargs):queryset models.Module.objects.all()ser ModuleSerializer(instancequeryset, manyTrue)return Response(ser.data)只显示id和name 只修改自定义序列化类ModuleSerializer即可如下 class ModuleSerializer(serializers.ModelSerializer):class Meta:model models.Module# fields __all__# fields [id, name] # 显示想要显示的字段exclude [course] # 排除掉course显示id、name和课程名称 class ModuleSerializer(serializers.ModelSerializer):cname serializers.CharField(sourcecourse.title) # 定义连表需要显示的字段class Meta:model models.Module# fields __all__fields [id, name, cname] # 显示想要显示的字段显示id、name、课程名称和级别 # 修改表结构模块表添加级别字段class Module(models.Model):模块表level_choise {1: 初级,2: 中级,3: 高级,}level models.ImageField(verbose_name级别,choiceslevel_choise,default1)name models.CharField(verbose_name模块名,max_length32)course models.ForeignKey(verbose_name课程, toCourse, on_deletemodels.CASCADE)class ModuleSerializer(serializers.ModelSerializer):cname serializers.CharField(sourcecourse.title) # 定义连表需要显示的字段level_test serializers.CharField(sourceget_level_display) # 定义本表需要显示的字段(以中文显示)class Meta:model models.Modulefields [id, name, level_test, cname] # 显示想要显示的字段# 显示结果[{id: 1,name: 数据结构,level_test: 初级,cname: Python},{id: 2,name: 正则表达式,level_test: 初级,cname: Python} ]5.9 单条数据展示、增加 基于CreateAPIView,RetrieveAPIView等系列实现对module表单条数据展示、增加 urlpatterns [re_path(api/(?Pversion\w)/module/new/$, views.ModuleNewView.as_view()), # 只对应POST方法re_path(api/(?Pversion\w)/module/new/(?Ppk\d)/$, views.ModuleNewView.as_view()), # 只对应GET方法 ]class ModuleNewSerializer(serializers.ModelSerializer):class Meta:model models.Modulefields __all__from rest_framework.generics import ListAPIView, CreateAPIView,RetrieveAPIViewclass ModuleNewView(CreateAPIView,RetrieveAPIView,):queryset models.Module.objects.all()serializer_class ModuleNewSerializer 5.10 对module表实现增删改查 基于ModelViewSet实现对module表实现增删改查 urlpatterns [re_path(api/(?Pversion\w)/module/set/$, views.ModuleSetView.as_view({get:list,post:create})),re_path(api/(?Pversion\w)/module/set/(?Ppk\d)/$, views.ModuleSetView.as_view({get:retrieve,delete:destroy,patch:partial_update,put:update})), ]class ModuleSetSerializer(serializers.ModelSerializer):class Meta:model models.Modulefields __all__from rest_framework.viewsets import ModelViewSetclass ModuleSetView(ModelViewSet):queryset models.Module.objects.all()serializer_class ModuleSetSerializer# 重写partial_update方法实现部分更新也可以不重写因为源码里也是如此实现的def partial_update(self, request, *args, **kwargs):pk kwargs.get(pk)module_object models.Module.objects.filter(idpk).first()ser ModuleSetSerializer(instancemodule_object,datarequest.data,manyFalse,partialTrue)if ser.is_valid():ser.save()return Response(成功)return Response(ser.errors)5.11 多对多表操作 对Video表做接口获取视频列表、单条视频信息 urlpatterns [re_path(api/(?Pversion\w)/video/$, views.VideoView.as_view()),re_path(api/(?Pversion\w)/video/(?Ppk\d)/$, views.VideoView.as_view()), ]class VideoSerializer(serializers.ModelSerializer):class Meta:model models.Videofields __all__class VideoView(ListAPIView, CreateAPIView):queryset models.Video.objects.all()serializer_class VideoSerializer对Video表做增删改查 多对多定制显示操作 # 这样定义可以省略{get:list,post:create...}from django.urls import path, re_path, include from rest_framework import routers from api import viewsroute routers.DefaultRouter() route.register(rvideo_set, views.VideoSetView)urlpatterns [re_path(api/(?Pversion\w)/,include(route.urls)) ]# 打印出多对多关联表的内容class VideoSetSerializer(serializers.ModelSerializer):tag_test serializers.SerializerMethodField() # 多对多定制显示操作class Meta:model models.Videofields [id, title, vid, tag, tag_test]# 钩子函数(get_自定义字段)每次展示钩子函数都会执行一遍# obj表示每次展示每条数据对象def get_tag_test(self, obj):# 与之关联的tag表中的所有数据tag_list obj.tag.all()return [{id: row.id, caption: row.caption} for row in tag_list]class VideoSetView(ModelViewSet):queryset models.Video.objects.all()serializer_class ser.VideoSetSerializer6. drf提供了哪些功能 1、免除csrftoken的认证 2、提供了一些视图类APIView、ListAPIView、ModelViewSet他的内部帮助我们写了get/post/delete...方法帮助我们可以快速实现增删改查。 3、渲染器页面的渲染。 4、序列化表单验证序列化 5、解析器解析request.body中的数据格式并将其赋值到request.data中。 6、版本控制7. drf总结 1、HTTP请求方法有哪些方法是干什么的 get/post/put/patch/delete2、用drf做接口开发数据显示 单表最简单定义files字段即可FK基于source参数连表操作M2M基于SerializerMethodField 自定义一个钩子方法注意choise显示中文可以使用source字段 get_字段名_display 3、有三种写接口的方法 APIViewListAPIViewModelViewSet 4、局部更新 局部更新应用用patch请求
http://www.zqtcl.cn/news/151890/

相关文章:

  • 琪觅公司网站开发中文网页开发工具
  • 教育网站制作设计成都网络营销公司
  • 怎么查看一个网站页面的seo优化情况网站建站建设首选上海黔文信息科技有限公司2
  • 威海网站建设价格深圳优美网络科技有限公司
  • 做网站用什么系统建设网站投资多少
  • 凡科建站官网 网络服务抚顺 网站建设
  • 学校网站的建设方案西安企业seo外包服务公司
  • 建设租车网站深圳ww
  • 推广网络网站潜江资讯网一手机版
  • 凡科网站自己如何做毕设 做网站
  • 一起做网站逛市场百度权重查询网站
  • 专业网站优化推广网站核查怎么抽查
  • 牡丹江站salong wordpress
  • 网站建设公司做网站要多少费用有哪些外国网站国内可以登录的
  • 天津建站平台网页制作免费的素材网站
  • 建设网站需要专业哪个企业提供电子商务网站建设外包
  • 公司网站建设及维护网站建设思维
  • 那个网站可以学做西餐17做网站广州沙河
  • 品牌网站建设哪里好京东网站建设案例
  • 亚马逊海外版网站深圳市工商注册信息查询网站
  • 新乐做网站优化网站上漂亮的甘特图是怎么做的
  • 新网站应该怎么做seo品牌推广方案思维导图
  • 想要网站导航推广页浅谈中兴电子商务网站建设
  • 免费引流在线推广成都网站优化费用
  • 老河口市网站佛山市点精网络科技有限公司
  • word模板免费网站seo引擎优化是做什么的
  • 办网站怎么赚钱鄠邑建站 网站建设
  • 宜春网站建设推广微信小程序开发
  • 巴南城乡建设网站免费网站建设软件大全
  • 湖南网站建设公公司没有自己的网站