ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

django rest framework系列02-引入rest使用APIView实现用户登录且保存Token

2021-01-07 23:29:35  阅读:281  来源: 互联网

标签:02 models APIView self request rest token user ._


1、数据库简单设计:

from django.db import models

class UserInfo(models.Model):
    user_type_choices =(
        (1,'普通用户'),
        (2,'VIP用户'),
        (3,'SVIP用户'),
    )
    user_type = models.CharField(max_length=2,choices=user_type_choices) #用户类型
    username = models.CharField(max_length=32)#用户明
    password = models.CharField(max_length=64)#密码
    #定义object方式pycharm代码提示不出来
    object  =models.Manager()

class UserToken(models.Model):
    user = models.OneToOneField(to='UserInfo',on_delete=models.CASCADE) #一对一关系指向UserInfo表
    token = models.FileField(max_length=64) #保存token值
    # 定义object方式pycharm代码提示不出来
    object = models.Manager()

2、views登录

from rest_framework.views import APIView
from django.http import JsonResponse
from API import models


def md5(user):
    '''
    通过MD5讲user+时间戳加密成MD5字符串
    :param user:
    :return:
    '''
    import hashlib
    import time
    ctime = str(time.time())
    m = hashlib.md5(bytes(user,encoding='utf-8'))
    m.update(bytes(ctime,encoding='utf-8'))
    return m.hexdigest()

class authView(APIView):

    def post(self,request,*args,**kwargs):
        ret = {'code':1000,'msg':None}
        try:
            user = request._request.POST.get('username')  #从request.method获取用户提交为什么是这样看下面解释
            pwd = request._request.POST.get('password')
            obj = models.UserInfo.object.filter(username=user,password=pwd).first() #数据库中查找用户
            print(obj)
            if not obj:
                #判断obj是否空如果空则没有查到用户名密码错误!
                ret['code'] = 1001
                ret['msg'] = '用户名密码错误!'
                return JsonResponse(ret)
            #登录成功,生成token
            token = md5(user)
            #保存token 到数据库  updata_or_create方法存在则更新,不存在则创建。
            #user字段等于obj刚才查到的用户,token等于我们通过user+时间戳生成的token
            models.UserToken.object.update_or_create(user=obj,defaults={'token':token})
            ret['token'] = token
            ret['msg'] = '登录成功'
        except Exception as e:
            ret['code'] = 1002
            ret['msg'] = '请求异常'+ str(e)

        return JsonResponse(ret)

以上views中关于 request取username为什么加_request解释:

第一片中解释了CBV模式中URL中定义的as_view()方法其实先执行的是self.dispatch(),其实这个方法已经对刚开始的request做了封装:

代码流程:

2.1、dispatch内部已经对request进行了重新赋值。那么进入initialize_request中看看做了什么操作。

    def dispatch(self, request, *args, **kwargs):
        """
        `.dispatch()` is pretty much the same as Django's regular dispatch,
        but with extra hooks for startup, finalize, and exception handling.
        """
        self.args = args
        self.kwargs = kwargs
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request

 

2.2、initialize_request中return了一个新的对象(第一个参数就是原始的request),那么再进入。Request

    def initialize_request(self, request, *args, **kwargs):
        """
        Returns the initial request object.
        """
        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
        )

2.3、 其他代码不用看,直接看self._request = request,封装好的request把原始的request放到了带下划线的request中。所有我们views中如果需要用原始的request传递的参数必须像视图中那样写。

 def __init__(self, request, parsers=None, authenticators=None,
                 negotiator=None, parser_context=None):
        assert isinstance(request, HttpRequest), (
            'The `request` argument must be an instance of '
            '`django.http.HttpRequest`, not `{}.{}`.'
            .format(request.__class__.__module__, request.__class__.__name__)
        )

        self._request = request
        self.parsers = parsers or ()
        self.authenticators = authenticators or ()
        self.negotiator = negotiator or self._default_negotiator()
        self.parser_context = parser_context
        self._data = Empty
        self._files = Empty
        self._full_data = Empty
        self._content_type = Empty
        self._stream = Empty

3、urls.py

from API import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/v1/auth/',views.authView.as_view()),
]

总结: 视图类继承rest_framework 的APIView,而APIView继承与Django的view。所有方法都是相同,先调用dispatch,方法。这一堆继承下来,内部添加不不少其他方法。

 

标签:02,models,APIView,self,request,rest,token,user,._
来源: https://blog.csdn.net/gjbfyhbfg/article/details/112341169

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有