day96-day98-media configuration & token aging & models field auto_XX

day96-day98-media configuration & token aging & models field auto_XX

1. It involves the media settings of image upload, which is generally only configured once in the project

1.1 The class table in models has a field for image upload

1.2 Configuration in settings

# mediaConfiguration
MEDIA_URL = "media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")

1.3 Configuration in the project urls.py

from django.conf.urls import url, include
from django.contrib import admin
# Copy
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')),
    # Copy
    url(r'media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT})
]

1.4 After the project is started, a media folder will be generated in the project directory, which stores the uploaded pictures

1.5 Return the image field to the front end in the serializer

2. Registration and login

2.1 Serializer

from rest_framework import serializers
from course import models
import hashlib


# Register & Login Serializer
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,
            # This is the ciphertext password transmitted by the analog front end
            pwd=hashlib.md5(pwd.encode()).hexdigest()
        )

        return user_obj

2.2 Registration and login view

# 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


# Register view
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('Registration is successful!-->{}'.format(ser_obj.data))
        except Exception as error:
            error = error
            return Response('Registration exception!')
        return Response('Registration failed!')


# Login view
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 ='Username or password cannot be empty'
        else:
            try:
                user_obj = models.Account.objects.filter(
                    username=username,
                    pwd=pwd
                ).first()
                if not user_obj:
                    login_obj.code = 1020
                    login_obj.error ='User name or password is wrong'
                else:
                    user_obj.token = uuid.uuid4()
                    user_obj.save()
                    login_obj.msg ='Login successful'
                    # Return token after login
                    login_obj.token = user_obj.token
            except Exception as e:
                e = e
        # Object calls __dict__, returns object attribute key-value pairs
        return Response(login_obj.__dict__)

2.3my_response.py, as a use, can realize the decoupling of return information

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

3. Regarding authentication type verification token whether expired

3.1 First of all, the fields in models must exist models.DateTimeField(auto_now=True)

3.2 The difference between auth_now and auth_now_add is also described in 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)

Then there are two ways to update the data to affect auto_now:

# 1.update method:
models.Book.objects.filter(title='asd').update(title='ads')
# .update() method does not change the time of date, it still saves the point in time when it was created


# 2.save() method:
obj = models.Book.objects.filter(title='asd').first()
obj.title='ads'
obj.save()
# .save() method is to save the time point of the change

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)

At this time, both the update method and the .save() method are invalid for time.

So how do we manually change the time?

Methods as below:

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

3.3 The certification code is as follows

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

1.2 The now() function returns the time in the current time zone

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


# Authentication class
class MyAuthentication(BaseAuthentication):
    def authenticate(self, request):
        """Get the token from the message header"""
        token = request.META.get('HTTP_AUTHENTICATE','')
        print(request.META)
        if not token:
            raise AuthenticationFailed('token cannot be empty')
        user_obj = models.Account.objects.filter(token=token).first()
        if not user_obj:
            raise AuthenticationFailed('token is illegal')
        
        """Get the last login time"""
        old_time = user_obj.create_token_time
        """now() will return the time in the local time zone"""
        now_time = now()
        """Judging whether the token is expired"""
        if (now_time-old_time).seconds> 20:
            raise AuthenticationFailed('token has expired, please log in again')

        return user_obj, token

3.4 About getting the token from the message header

3.5 Judgment of token expiration time, hour, minute, second, pay attention to 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


# Authentication class
class MyAuthentication(BaseAuthentication):
    def authenticate(self, request):
        if request.method =='OPTIONS':
            return None
        """Get the token from the message header"""
        token = request.META.get('HTTP_AUTHENTICATE','')

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

        if not token:
            raise AuthenticationFailed('token cannot be empty')
        user_obj = models.Account.objects.filter(token=token).first()
        if not user_obj:
            raise AuthenticationFailed('token is illegal')

        """Get the last login time"""
        old_time = user_obj.create_token_time
        """now() will return the time in the local time zone"""
        now_time = now()
        """Judging whether the token is expired"""
        if (now_time-old_time).seconds> 100000:
            raise AuthenticationFailed('token has expired, please log in again')

        return user_obj, token
Reference: https://cloud.tencent.com/developer/article/1603115 day96-day98-media configuration & token aging & models field auto_XX-Cloud + Community-Tencent Cloud