Django project exercise - user table development & video table structure development

Posted by skbanta on Wed, 17 Nov 2021 08:08:16 +0100

User related development, client table structure development

1, User table development

Create a new model package in the app to store database related files, and then create an auth py file in it.

Under the auth file in the model, we create a clientUser, user table:

# coding:utf-8

import hashlib  # Used to encrypt passwords
from django.db import models


# Password encryption
def hash_password(password):
    if isinstance(password, str):
        password = password.encode('utf-8')
    return hashlib.md5(password).hexdigest().upper()  # hash md5 encryption, then hexadecimal, uppercase


class ClientUser(models.Model):

    username = models.CharField(max_length=50, null=False, unique=True)
    password = models.CharField(max_length=255, null=False)
    avatar = models.CharField(max_length=500, default='')  # You can also use urlfield
    gender = models.CharField(max_length=10, default='')
    birthday = models.DateTimeField(null=True, blank=True, default=None)
    status = models.BooleanField(default=True, db_index=True)
    create_time = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return 'username:{} '.format(self.username)

    # django's user is using create_user can automatically encrypt the password, but not here. You need to write one by hand
    @classmethod
    def add(cls, username, password, avatar='', gender='', birthday=None):
        return cls.objects.create(
            username=username,
            password=hash_password(password),
            avatar=avatar,
            gender=gender,
            birthday=birthday,
            status=True
        )

isinstance() function to determine whether an object is a known type, similar to type().

The difference between isinstance() and type():

type() does not consider a subclass as a parent type and does not consider inheritance.

isinstance() will consider the subclass as a parent type and consider the inheritance relationship.

If you want to judge whether the two types are the same, isinstance() is recommended.

Here, we encrypt the password manually, and then we enter the debugging mode to see what the encrypted password looks like:

In [1]: from app.model.auth import hash_password

In [2]: password = hash_password('cong')

In [3]: password
Out[3]: '3DE6A8F9608DDD4BA89F97B36D7587D6'

Get user method:

# Get user
    @classmethod
    def get_user(cls, username, password):
        # Because get will throw an exception if it cannot get it, try catch is used here
        try:
            user = cls.objects.get(
                username=username,
                password=hash_password(password)
            )
            return user  # Get returned user
        except:
            return None  # Unable to get, return None

The classmethod is defined here because you want to get the contents of the whole table, and the following password modification is only to get the data of a user, so you don't need a class method, just self.

Change Password:

# To obtain the old password and the new password, verify that the old password is correct before changing to the new password
    def update_password(self, old_password, new_password):
        hash_old_password = hash_password(old_password)
        
        if hash_old_password != self.password:  # The old password entered is not equal to our previous password
            return False
        
        hash_new_password = hash_password(new_password)  # If the password is verified, take the new we get_ Password hash
        self.password = hash_new_password
        self.save()  # Save the new password
        
        return True

User status change

# User status change
    def update_status(self):
        self.status = not self.status  # If the state is reversed, the state is changed
        self.save()
        
        return True

2, Development of video related database

In the model folder, create another video file
The main table of video is as follows:

# coding:utf-8

from enum import Enum  # In Python 3, the enumeration is a package that exists by default. The priority is higher than django and placed at the top
from django.db import models


# Type of video
class VideoType(Enum):
    movie = 'movie'
    cartoon = 'cartoon'
    episode = 'episode'
    variety = 'variety'
    other = 'other'


VideoType.movie.label = 'film'  # Label him
VideoType.cartoon.label = 'comic'
VideoType.episode.label = 'Drama series'
VideoType.variety.label = 'variety'
VideoType.other.label = 'other'


# Video sources are still defined by enumeration
class FromType(Enum):
    youku = 'youku'
    custom = 'custom'


FromType.youku.label = 'Youku'
FromType.custom.label = 'self-control'


# Define video country enumeration
class NationalityType(Enum):
    china = 'china'
    japan = 'japan'
    korea = 'korea'
    america = 'america'
    other = 'other'


NationalityType.china.label = 'China'
NationalityType.japan.label = 'Japan'
NationalityType.korea.label = 'the republic of korea'
NationalityType.america.label = 'U.S.A'
NationalityType.other.label = 'other'


# Main table of video
class Video(models.Model):
    name = models.CharField(max_length=100, null=False)
    image = models.CharField(max_length=500, default='')  # Poster image of video
    video_type = models.CharField(max_length=50, default=VideoType.other.value)  # type is the Python keyword. Value can get the value passed later
    from_to = models.CharField(max_length=20, null=False, default=FromType.custom.value)  # Video source
    nationality = models.CharField(max_length=20, default=NationalityType.other.value)
    info = models.TextField()  # describe
    status = models.BooleanField(default=True, db_index=True)  # Is video status available
    created_time = models.DateTimeField(auto_now_add=True)  # The time is modified only when it is created for the first time
    updated_time = models.DateTimeField(auto_now=True)  # Each modification modifies the current time
    
    # Combine unique indexes, combine multiple indexes, and then supplement parents
    class Meta:
        unique_together = ('name', 'video_type', 'from_to', 'nationality')
        
    def __str__(self):
        return self.name

db_index establishes a database index on a field in the model.

Define an actor schedule:

# Define an actor schedule
class VideoStar(models.Model):
    video = models.ForeignKey(Video, 
                              related_name='video_star', 
                              on_delete=models.SET_NULL, 
                              blank=True,
                              null=True
                              )
    name = models.CharField(max_length=100, null=False)
    identity = models.CharField(max_length=50, default='')  # Identity, director and starring..
    
    # Uniqueness
    class Meta:
        unique_together = ('video', 'name', 'identity')
        
    def __str__(self):
        return self.name

Related in foreign keys_ Name, the object of the main table can be related through this_ Name reverse lookup to find the objects in the attached table associated with the object in the main table. Table 1.related_name.get() . Related here_ Name is replaced by related_ Just the value in name. You can find the star object corresponding to the movie object.

Video related subsidiary tables:

# Attached table of video: such as video address and number of play sets
class VideoSub(models.Model):
    video = models.ForeignKey(Video,
                              related_name='video_sub',
                              on_delete=models.SET_NULL,
                              blank=True,
                              null=True
                              )  # Foreign keys are the same as above
    url = models.CharField(max_length=500, null=False)
    number = models.IntegerField(default=1)  # Set number
    
    class Meta:
        unique_together = ('video', 'number')
    
    def __str__(self):
        return 'video:{}  number:{} '.format(self.video.name, self.number)

Note: another point is that when creating foreign keys, on_delete=models.SET_NULL, so you must add: null=True
I didn't add it at first, so I reported an error:

3, Synchronize database

python manage.py makemigrations

Prompt: No changes detected.
Because what you really want to read is the data in the models.py file in the app directory
Therefore, we need to introduce the table we just wrote into models:

# coding:utf-8

from .model.auth import ClientUser
from .model.video import Video, VideoStar, VideoSub

Then after updating the database, it is created

Then migrate.

Topics: Python Django git