drf1-1.5

drf source

1567937996087

#  CBV 类型的全是根据反射来的,基于反射实现根据请求方式不同,执行不同的方法
#  原理 :
    # a. 
    url - view()  - dispath
class StudentsView(View):
    def dispatch(self, request, *args, **kwargs):
        func = getattr(self, request.method.lower())
        ret = func(request, *args, **kwargs)  # 各个函数执行,以及参数 get()....
        return ret
    def get(self,request):
        return HttpResponse('GET')

cbv of running processes

   def dispatch(self, request, *args, **kwargs):
        ret = super(StudentsView, self).dispatch(request, *args, **kwargs)
        return ret

1567938861888

Inheritance: (a plurality of common functionality class, to avoid repetition)

Interview questions

  1. django middleware

    • Middleware can write up to several methods: 5
    • process_request view response exception
    • render_template
  2. Implementation process

  3. What middleware done?

    Competence

    User login authentication

    django csrf_token how to achieve? (interview questions)

    In view which: request view request before all

    • from django.views.decorators.csrf import csrf_exempt
    • csrf_excmpt exemption request csrf

    • 1567939934152

      process_view method

      Check whether the @csrf_exempt (exempt csrf certification)

      To request or obtain token cookie weight

      Why is the view, the request is executed after the view to the decorator

CBV little knowledge:

Method ineffective when applied alone csrf

class:...
# @csrf_exempt  # 这么加不行
# @method_decorator(csrf_exempt)
def post(self, request):
    return HttpResponse('POST')

Which must be added to dispath

 @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        func = getattr(self, request.method.lower())
        ret = func(request, *args, **kwargs)  # 各个函数执行,以及参数 get()....
        return ret

Or a class on

@method_decorator(csrf_exempt, name='dispatch')
class StudentsView(View):

Write a distpatch method may be less

to sum up:

  • Nature: based on the reflection to achieve
  • Process: Route view dispatch (reflection)
  • csrf_token not canceled from the middleware, to be applied to the class or dispatch csrf_exempt
  • Spread
    • csrf
      • Middleware based proces_view
      • Function is provided to the individual decorator or NA

restful specification (recommended)

Separating the front and rear end development

A:
http://www.oldboyedu.com/add_user/ user management ....

Many return value, return value, the deal is not good

​ {

​ code:666,

​ }

b:

view

​ $.ajax({})

#不好, 因为10张表 处理  ,就40条url了
# 规范 : 10个url , 用method来处理不同的

Based fbv write

# 1 根据method不同进行不同的处理
def order(request):
    if request.method == "GET":
        return HttpResponse('获取')
    if request.method == "add":
        return HttpResponse('获取')
    if request.method == "del":
        return HttpResponse('获取')
    if request.method == "update":
        return HttpResponse('获取')

Based cbv write

class orderView(View):
    def get(self,request,*args,**kwargs):
        return HttpResponse('获取')
    def post(self,request,*args,**kwargs):  # 创建
        return HttpResponse('获取')
    def put(self,request,*args,**kwargs):   # 更新
        return HttpResponse('获取')
    def delete(self,request,*args,**kwargs):
        return HttpResponse('获取')

Distinguish 2 domain (cross-domain to solve the problem):

​ www.luffycity.com

Distinguish api.luffycity.com on subdomains

url way:

​ www.luffycity.com

​ www.luffycity.com/api

Way version

www.luffycity.com/api/v1/#

3 Resource Oriented Programming

Everything on the Internet as a resource,

4 Try to use nouns

5 method (5) put on a server update, all update

patch :() partial update

6 filter

www.luffycity.com/api/v1/?status=1

7 status codes

Status codes and code used in conjunction with, the multi-code representation, the front end might be willing to process

8 Back to Results

1567942443696

9 h ... themselves splicing url

Above may not follow, as the case may be,

restful api specifications are what? Talk about your perception of him

Disguised as a veteran, storytelling

In using his time, some adaptation, some do not, there is a problem, and the cross-domain,

Solve: cors

jsonp ..

In the chat, well, then use that

2.djangorestframework framework

pip3 install djangorestframework

Operation may be performed with a token

1567998500855

1567998490695

from rest_framework.views import APIView
from rest_framework.authentication import BaseAuthentication
from rest_framework import  exceptions
# 登录认证基于这个类实现
# dispatch->reuqest(封装)->认证(initial)->per():request.user->user->获取认证对象-->类对象--->触发异常或者是token(正常)  # 写了一个My的类,写了一个auth_calssess , 有的话就找本类的,没有就去父类里找
class Myauthentication(object):
    def authenticate(self,request):
        token = request._request.GET.get('token')
        if not token:
            raise exceptions.AuthenticationFailed('用户认证失败')
        return ('alex',None)
    def authenticate_header(self,val):
        pass
class DogView(APIView):
    # authentication_classes = [BaseAuthentication, ]  # 获取的是类的对象,
    authentication_classes = [Myauthentication, ]  # 获取的是类的对象,

    # self.dispatch
    def get(self, request, *args, **kwargs):
        ret = {
            'code': 1000,
            'msg': 'xxx'
        }
        return HttpResponse(json.dumps(ret), status=201)

    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')

For this class do serious

dispatch

A. Certification

a. Certification

Source process thoroughly understand: do not understand, add a comment, entrance

dispatch, will not only use, but also to understand the principle

s7129

Today: 1 Certification 2 3 throttle rights (access frequency control) version 4

1568000733364

Use user authentication, you need to write a class, and then write a subject that [,]

It can also be used globally

1568015600768

b. using basic authentication unit

  • solve:
    • a. Create two tables
    • b. User login (return token and saved to the database)

c. Source

1568015825015

1568017683422

authentication_classes = [Authtication,]
#  self.dispatch 入口
def dispatch(self, request, *args, **kwargs):
   self.args = args
        self.kwargs = kwargs
        # 对原生的request进行加工(追加)
        # Request(request,parsers=self.get_parsers(),   authenticators=self.get_authenticators(),  negotiator=self.get_content_negotiator(),    parser_context=parser_context)
        # request(原生request,  [BaseAuthentication对象,], )
        # 获取原生request, self._request
        # 获取认证类的对象, request.authenticator
        # 1.封装Request
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?
        
 try:
            # 2. 认证成功,走反射
            self.initial(request, *args, **kwargs)

            # Get the appropriate handler method
            if 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_allowed

            response = handler(request, *args, **kwargs)
        
        # 认证失败,抛异常
        except Exception as exc:
            response = self.handle_exception(exc)
def initialize_request(self, request, *args, **kwargs):
    parser_context = self.get_parser_context(request)
    return Request(
        request,
        parsers=self.get_parsers(),
        authenticators=self.get_authenticators(),
        negotiator=self.get_content_negotiator(),
        parser_context=parser_context
    )
    def get_authenticators(self):
        # self.authentication_classes = [foo,bar]
        return [auth() for auth in self.authentication_classes]
#对象,然后,自己写了这个类,和

as follows:

from rest_framework.authentication import BaseAuthentication

# 重写这两个方法
def authenticate(self, request):
def authenticate_header(self, request): # pass就行
authentication_classes = [Authtication,]
# 用了drf , 对于重用的功能
class Authtication(object):
    def authenticate(self,request):
        token = request._request.GET.get('token')
        token_obj = models.UserToken.objects.filter(token=token).first()
        if not token_obj:
            raise exceptions.AuthenticationFailed('用户认证失败')
        # 在rest_framework内部会将整个两个字段赋值给request,以供后续操作使用
        return (token_obj.user, token_obj)

    def authenticate_header(self, request):
        pass
def initial(self, request, *args, **kwargs):
# 4.实现认证
    self.perform_authentication(request)
def perform_authentication(self, request):
    request.user

request.user in the Request.py

@property
def user(self):
    if not hasattr(self, '_user'):
        with wrap_attributeerrors():
            # 获取认证对象, 进行一步步的认证
            self._authenticate()
    return self._user
[BaseAuthentication对象,]
 def _authenticate(self):
        # [BaseAuthentication对象,]
        # 循环认证类的所有对象
        for authenticator in self.authenticators:
            try:
                # 执行认证类的authenticate方法
                # 1.如果auth方法抛出异常,self._not_auth()执行
                # 2.有返回值,必须得是元祖(request.user, request.auth)
                # 3.返回None , 当前不处理,下一个认证来处理
                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._not_authenticated()

    def _not_authenticated(self):
        self._authenticator = None
        if api_settings.UNAUTHENTICATED_USER:
            self.user = api_settings.UNAUTHENTICATED_USER() # AnonymousUser
        else:
            self.user = None
        if api_settings.UNAUTHENTICATED_TOKEN:
            self.auth = api_settings.UNAUTHENTICATED_TOKEN() # None
        else:
            self.auth = None

Executes the function, the function returns

return (token_obj.user, token_obj), according to written here and abnormal neuron progenitor return

d. Code Configuration p = 19

The writing class, returns Ganso certified, return the exception, writes setting in

All classes are then added to the default, not in a single write a

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': ['api.utils.auth.FirstAuthtication', 'api.utils.auth.Authtication' ]
}

Global can use, do not use topical

class UserInfoView(APIView):
    """订单相关业务"""
    # 类似于中间件, 装饰器的处理restframework的方法,认证登录方法
    authentication_classes = []
    def get(self, request, *args, **kwargs):
        return HttpResponse('用户信息')

http://127.0.0.1:8000/api/v1/order/?token=851c293fe784dea90e079aad5d498f42

{
    "code": 1000,
    "msg": null,
    "data": {
        "1": {
            "name": "xifu",
            "age": 18,
            "gender": "男",
            "content": "..."
        },
        "2": {
            "name": "xifu2",
            "age": 18,
            "gender": "男",
            "content": "..."
        }
    }
}

http://127.0.0.1:8000/api/v1/order/

The user is not logged in

In the final, _not_authenticated function

if api_settings.UNAUTHENTICATED_USER:
    self.user = api_settings.UNAUTHENTICATED_USER() # AnonymousUser
else:
    self.user = None

if api_settings.UNAUTHENTICATED_TOKEN:
    self.auth = api_settings.UNAUTHENTICATED_TOKEN() # None
api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)


def reload_api_settings(*args, **kwargs):
    setting = kwargs['setting']
    if setting == 'REST_FRAMEWORK':
        api_settings.reload()

Therefore, in settings where the use of global settings, USER, and TOKEN

authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES

REST_FRAMEWORK = {
    # 全局使用的认证类
    # 'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.auth.FirstAuthtication', 'app01.utils.auth.Authtication' ],
    'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.auth.FirstAuthtication', ],

    "UNAUTHENTICATED_USER":    None, # 匿名用户, request.user= None
    # 'UNAUTHENTICATED_TOKEN':None ,  # request.auth = None
}

api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)

In the settings rest_framework in

api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
def reload_api_settings(*args, **kwargs):
    setting = kwargs['setting']
    if setting == 'REST_FRAMEWORK':
        api_settings.reload()

Anonymous is request.user = None

Not modal dialog

1568021678285

1568021689065

Provided by the browser, and then fill out, encryption

1568021725261

Based on django to achieve

Will not use these, are custom realized

e. built-in authentication class

  • Certification classes must inherit: from rest_framework.authentication import BaseAuthentication

  • Other certification categories:

Sort:

  1. use

    • Create a class: method implementation inheritance BaseAuthentication auth ..

    • return value:

      • None, next to perform certification
      • Throws exceptions.AuthenticationFailed ( 'User authentication failed') #from rest_framework import exceptions
      • (Element 1, element 2) # 1 assigned to the elements of the request.user; element 2 is assigned to request.auth
    • Topical

    • class Authtication(object):
          def authenticate(self,request):
              token = request._request.GET.get('token')
              token_obj = models.UserToken.objects.filter(token=token).first()
              if not token_obj:
                  raise exceptions.AuthenticationFailed('用户认证失败')
              # 在rest_framework内部会将整个两个字段赋值给request,以供后续操作使用
              return (token_obj.user, token_obj)
      
          def authenticate_header(self, request):
              pass
    • Global Use

    • REST_FRAMEWORK = {
          # 全局使用的认证类
          # 'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.auth.FirstAuthtication', 'app01.utils.auth.Authtication' ],
          'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.auth.FirstAuthtication', ],
      
          "UNAUTHENTICATED_USER": None,  # (没登录) 匿名用户, request.user= None   # 返回的是函数()所以写匿名函数
          # 'UNAUTHENTICATED_TOKEN':None ,  # request.auth = None
      }

2. Source Process

Go first dispatch, request package, and take the initial, find all the objects, execute methods (two) can be set in the setting, but it api.settings Why and settings associated with, do not understand

  • dispatch

    • Package request

    Acquiring authentication class definitions (global / local), by the formula to create the object list

  • initial

    • perform_authentication
      • request.user (inner loop ...)

Things behind and certification process here is the same

II. Permissions

Certification. User_type 1234 when you can have access

1568022484654

Problem: no view can be accessed without permission

Also through the dispatch to 4,

到check_permissions

Question 1 encounter

在设置超级vip时,返回的值是1
if request.user.user_type != 1:
    return HttpResponse('无权访回')
    
AttributeError: 'NoneType' object has no attribute 'user_type'    

Because I was set up to give him permission

    # 全局使用的认证类
   # 'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.auth.FirstAuthtication', 'app01.utils.auth.Authtication' ],
     'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.auth.FirstAuthtication', ],

Returns empty instead request.user and request.auth, it returns empty

Setting a supervisor vip

According user_type judge each object, and some gave him a super vip, another default does not handle, (where 1 is the vip)

if request.user.user_type != 1:
    return HttpResponse('无权访回')

Encapsulated into the class

# 认证过之后就开始权限认证了
class MyPermission(object):
    # self.dispatch
    def has_permission(self, request, view):
        # 把权限写入类里面
        if request.user.user_type != 1:
            return False
        return True  # 有权访问
class OrderView(APIView):    
    # 局部权限
    permission_classes = [MyPermission, ]

1568034481217

After all the open global certification, you can not handle auth yet?

class MyPermission1(object):
    def has_permission(self, request, view):
        # 把权限写入类里面
        if request.user.user_type == 3:
            return False
        return True  # 有权访问
class UserInfoView(APIView):
    """订单相关业务(普通用户/vip)"""
    # 类似于中间件, 装饰器的处理restframework的方法,认证登录方法
    # authentication_classes = []
    permission_classes = [MyPermission1, ]
    def get(self, request, *args, **kwargs):
        return HttpResponse('用户信息')

Completed the basic rights of

Look Source Process

dispatch
initial
check_permissions
              # [权限类的对象,权限类的对象,]
        for permission in self.get_permissions():
            # 通过per...为ture, 则not per..为false,不走, 而为false,则为ture,               走里面,抛异常
            if not permission.has_permission(request, self):
                self.permission_denied(
                    request, message=getattr(permission, 'message', None)
                )
                
def permission_denied(self, request, message=None):
"""
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(detail=message)                

Written global

utils
    -auth.py
    -permission.py
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ['app01.utils.permission.SVIPPermission']     # 全局的
}
# 认证过之后就开始权限认证了
class SVIPPermission(object):
    # self.dispatch
    message = '必须是SVIP才能访问'
    def has_permission(self, request, view):
        # 把权限写入类里面
        if request.user.user_type != 1:
            return False
        return True  # 有权访问
class MyPermission1(object):
    def has_permission(self, request, view):
        # 把权限写入类里面
        if request.user.user_type == 3:
            return False
        return True  # 有权访问

If you write in the global, then all can be used, if you do not use, for a field like

# permission_classes = [MyPermission1, ]

There is no built-in power?

There is a default return true

In order to standardize

from rest_framework.permissions import BasePermission
# 按照代码规范应该继承,内置的
class SVIPPermission(BasePermission):

Other permissions are written by django

1568036241344

Production environment, can not be the default things that are to write their own (custom, but also a higher level)

Sort:

  • 1. Restframework written permission of, the best written class, put his assembly

Must inherit: BasePermission, must implement: has_permission method

  • return value

    return False  #无权访问
    return True     #有权访问
  • Local:

    class UserInfoView(APIView):
        """订单相关业务(普通用户/vip)"""
        permission_classes = [MyPermission1, ] #加上这个
        def get(self, request, *args, **kwargs):
  • Global:

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

in the afternoon:

2 after landing to see what the user (vip or svip)

3, frequency of visits

Restrictions: for example, one minute how many times 6 times

Accessing a dictionary stored record ID number {=: [12: 10: 10,12: 10: 09,12: 10: 08]}

# 12:10:10,12:10:09,12:10:08,12:10:07,12:10:06,12:10:05

12:50:10

[12: 10: 10,12: 10: 09,12: 10: 08,] clear

12:10:11

[12: 10: 10,12: 10: 09,12: 10: 08] is greater than 3 times, not the

The ip, can be recorded

Access records = {user IP: [....]} // ip but you can change ah, no way, anonymous user, reptiles

Registered users can be restricted, so now the phone number binding, but the user name more, would not be able to do.

class VisitThrottle(object):
    def allow_request(self, request, view):
        # return True# 可以继续访问 # return False 表示访问频率太高,被限制
        return False
    def wait(self):
        pass

class AuthView(APIView):
    authentication_classes = []
    permission_classes = []
    throttle_classes = [VisitThrottle,]
{
    "detail": "Request was throttled."
}

Guess you like

Origin www.cnblogs.com/Doner/p/11495862.html