天天看点

day96-day98-media配置&token时效&models字段auto_XX1.涉及到图片上传的 media 设置,项目中一般仅配置一次2.注册与登录3.关于认证类校验token是否过期

1.涉及到图片上传的 media 设置,项目中一般仅配置一次

1.1models里面的类表有图片上传的字段

day96-day98-media配置&token时效&models字段auto_XX1.涉及到图片上传的 media 设置,项目中一般仅配置一次2.注册与登录3.关于认证类校验token是否过期

1.2settings里面的配置

day96-day98-media配置&token时效&models字段auto_XX1.涉及到图片上传的 media 设置,项目中一般仅配置一次2.注册与登录3.关于认证类校验token是否过期
# media配置
MEDIA_URL = "media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")           

复制

1.3项目urls.py里面的配置

day96-day98-media配置&token时效&models字段auto_XX1.涉及到图片上传的 media 设置,项目中一般仅配置一次2.注册与登录3.关于认证类校验token是否过期
from django.conf.urls import url, include
from django.contrib import admin
# 复制
from LuffyProject import settings
from django.views.static import serve

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/course/', include('course.urls')),
    url(r'^', include('login.urls')),
    url(r'^', include('pay.urls')),
    # 复制
    url(r'media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT})
]           

复制

1.4项目启动后,会在项目目录下生成一个 media 的文件夹,里面存放的是上传的图片

day96-day98-media配置&amp;token时效&amp;models字段auto_XX1.涉及到图片上传的 media 设置,项目中一般仅配置一次2.注册与登录3.关于认证类校验token是否过期

1.5序列化器里面返回图片字段给前端

day96-day98-media配置&amp;token时效&amp;models字段auto_XX1.涉及到图片上传的 media 设置,项目中一般仅配置一次2.注册与登录3.关于认证类校验token是否过期

2.注册与登录

2.1序列化器

from rest_framework import serializers
from course import models
import hashlib


# 注册&登录序列化器
class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Account
        fields = ['username', 'pwd']

    def create(self, validated_data):
        username = validated_data['username']
        pwd = validated_data['pwd']

        user_obj = models.Account.objects.create(
            username=username,
            # 这是模拟前端传递密文密码
            pwd=hashlib.md5(pwd.encode()).hexdigest()
        )

        return user_obj           

复制

2.2注册与登录视图

# Create your views here.
import uuid

from rest_framework.response import Response
from rest_framework.views import APIView

from course import models
from . import serializers
from utlils import my_response


# 注册视图
class RegisterView(APIView):
    @staticmethod
    def post(request):
        try:
            ser_obj = serializers.AccountSerializer(data=request.data)
            if ser_obj.is_valid():
                ser_obj.save()
                return Response('注册成功!-->{}'.format(ser_obj.data))
        except Exception as error:
            error = error
            return Response('注册异常!')
        return Response('注册失败!')


# 登录视图
class LoginView(APIView):
    @staticmethod
    def post(request):
        login_obj = my_response.LoginResponse()
        username = request.data.get('username', '')
        pwd = request.data.get('pwd', '')
        if not username or not pwd:
            login_obj.code = 1010
            login_obj.error = '用户名或密码不能为空'
        else:
            try:
                user_obj = models.Account.objects.filter(
                    username=username,
                    pwd=pwd
                ).first()
                if not user_obj:
                    login_obj.code = 1020
                    login_obj.error = '用户名或密码错误'
                else:
                    user_obj.token = uuid.uuid4()
                    user_obj.save()
                    login_obj.msg = '登录成功'
                    # 登录之后返回 token
                    login_obj.token = user_obj.token
            except Exception as e:
                e = e
        # 对象调用__dict__,返回对象属性键值对
        return Response(login_obj.__dict__)
           

复制

2.3my_response.py,作为使用,可以实现返回信息解耦

class LoginResponse:
    def __init__(self):
        self.code = 1000
        self.error = ''
        self.msg = ''           

复制

day96-day98-media配置&amp;token时效&amp;models字段auto_XX1.涉及到图片上传的 media 设置,项目中一般仅配置一次2.注册与登录3.关于认证类校验token是否过期

3.关于认证类校验token是否过期

3.1首先 models 里的字段一定存在 models.DateTimeField(auto_now=True)

day96-day98-media配置&amp;token时效&amp;models字段auto_XX1.涉及到图片上传的 media 设置,项目中一般仅配置一次2.注册与登录3.关于认证类校验token是否过期

3.2关于 auth_now 和 auth_now_add 的区别,day67也有讲述

3.2.1 auto_now=True

from django.db import models
class Book(models.Model):
    title = models.Charfield(max_length=32)
    date = models.Datefield(auto_now = True)           

复制

那么在更新数据是两种方法对auto_now的影响:

# 1.update方法:
models.Book.objects.filter(title='asd').update(title='ads')
# .update() 方法不会改变date的时间,还是保存着创建时的时间点


# 2.save()方法:
obj = models.Book.objects.filter(title='asd').first()
obj.title='ads'
obj.save()
# .save() 方法是保存了更改时的时间点           

复制

3.2.2 auto_now_add=True:

from django.db import models
class Book(models.Model):
    title = models.Charfield(max_length=32)
    date = models.Datefield(auto_now_add = True)           

复制

此时,update方法和.save()方法对时间都是无效的。

那么我们如何手动的更改时间呢?

方法如下:

models.Book.objects.filter(title='asd').update(date=datetime.datetime.now())           

复制

3.3认证类代码如下

1.1 token = request.META.get('HTTP_AUTHENTICATE','')

1.2 now() 函数返回当前时区的时间

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from course import models
from django.utils.timezone import now


# 认证类
class MyAuthentication(BaseAuthentication):
    def authenticate(self, request):
        """从消息头获得 token"""
        token = request.META.get('HTTP_AUTHENTICATE', '')
        print(request.META)
        if not token:
            raise AuthenticationFailed('token不能为空')
        user_obj = models.Account.objects.filter(token=token).first()
        if not user_obj:
            raise AuthenticationFailed('token不合法')
        
        """获取上一次登录的时间"""
        old_time = user_obj.create_token_time
        """now()将返回本地时区的时间"""
        now_time = now()
        """判断 token 是否过期"""
        if (now_time - old_time).seconds > 20:
            raise AuthenticationFailed('token已经过期,请重新登录')

        return user_obj, token           

复制

3.4关于从消息头获取 token

day96-day98-media配置&amp;token时效&amp;models字段auto_XX1.涉及到图片上传的 media 设置,项目中一般仅配置一次2.注册与登录3.关于认证类校验token是否过期

3.5token过期时间的判断,时、分、秒,注意 from django.utils.timezone import now

day96-day98-media配置&amp;token时效&amp;models字段auto_XX1.涉及到图片上传的 media 设置,项目中一般仅配置一次2.注册与登录3.关于认证类校验token是否过期
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from course import models
from django.utils.timezone import now


# 认证类
class MyAuthentication(BaseAuthentication):
    def authenticate(self, request):
        if request.method == 'OPTIONS':
            return None
        """从消息头获得 token"""
        token = request.META.get('HTTP_AUTHENTICATE', '')

        # print('request.META-->', request.META)

        if not token:
            raise AuthenticationFailed('token不能为空')
        user_obj = models.Account.objects.filter(token=token).first()
        if not user_obj:
            raise AuthenticationFailed('token不合法')

        """获取上一次登录的时间"""
        old_time = user_obj.create_token_time
        """now()将返回本地时区的时间"""
        now_time = now()
        """判断 token 是否过期"""
        if (now_time - old_time).seconds > 100000:
            raise AuthenticationFailed('token已经过期,请重新登录')

        return user_obj, token           

复制