天天看點

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           

複制