1.涉及到圖檔上傳的 media 設定,項目中一般僅配置一次
1.1models裡面的類表有圖檔上傳的字段

1.2settings裡面的配置
# media配置
MEDIA_URL = "media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
複制
1.3項目urls.py裡面的配置
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 的檔案夾,裡面存放的是上傳的圖檔
1.5序列化器裡面傳回圖檔字段給前端
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 = ''
複制
3.關于認證類校驗token是否過期
3.1首先 models 裡的字段一定存在 models.DateTimeField(auto_now=True)
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
3.5token過期時間的判斷,時、分、秒,注意 from django.utils.timezone import 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):
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
複制