1. 程式人生 > >Django課程內容資料模型

Django課程內容資料模型

一 編輯mysite/course/models.py

from django.db import models
from django.contrib.auth.models import User
from slugify import slugify
from .fields import OrderField

class Course(models.Model):
    user = models.ForeignKey(User, related_name='courses_user')
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200, unique=True)
    overview = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    student = models.ManyToManyField(User, related_name="courses_joined", blank=True)

    class Meta:
        ordering = ('-created',)

    def save(self, *args, **kargs):
        self.slug = slugify(self.title)
        super(Course, self).save(*args, **kargs)

    def __str__(self):
        return self.title

# 實現視訊和檔案分使用者存放
def user_directory_path(instance, filename):
    return "courses/user_{0}/{1}".format(instance.user.id, filename)


class Lesson(models.Model):
    user = models.ForeignKey(User, related_name='lesson_user')
    course = models.ForeignKey(Course, related_name='lesson')
    title = models.CharField(max_length=200)
    # 接收上傳的視訊
    video = models.FileField(upload_to=user_directory_path)
    description = models.TextField(blank=True)
    # 接收上傳附件
    attach = models.FileField(blank=True, upload_to=user_directory_path)
    created = models.DateTimeField(auto_now_add=True)
    # 用來儲存某課程內容在響應的課程標題Course中的序號
    order = OrderField(blank=True, for_fields=['course'])

    class Meta:
        # 按照order進行排序
        ordering = ['order']

    def __str__(self):
        return '{}.{}'.format(self.order, self.title)

二 建立子定義欄位屬性

from django.db import models
from django.core.exceptions import ObjectDoesNotExist

# 要哦物件排序的序號,其值為整數,所以繼承PositiveIntegerField
class OrderField(models.PositiveIntegerField):
    def __init__(self, for_fields=None, *args, **kwargs):
        self.for_fields = for_fields
        super(OrderField, self).__init__(*args, **kwargs)

    # Django欄位屬性中,都繼承了Field類,pre_save就是Field類中的一個方法
    # 該方法的作用是在資料儲存之前進行預處理,在某個具體欄位屬性中
    # 因為特殊的需求,常常將Field類中的這個方法重寫
    # 該方法具體實現:將最終例項的序號記錄下來
    def pre_save(self, model_instance, add):
        # 判斷當前例項是否有某個屬性
        # 計算新增一條資料後的序號
        if getattr(model_instance, self.attname) is None:
            try:
                # 得到當前例項的所有記錄
                qs = self.model.objects.all()
                print(qs)
                # <QuerySet [<Lesson: 0.大一英文>, <Lesson: 0.春節>, <Lesson: 1.傳統佳節>]>
                if self.for_fields:
                    query = {field: getattr(model_instance, field) for field in self.for_fields}
                    qs = qs.filter(**query)
                last_item = qs.latest(self.attname)
                # 得到最後一條記錄,並加1
                value = last_item.order + 1
            except ObjectDoesNotExist:
                value = 0
            setattr(model_instance, self.attname, value)
            # 得到新增記錄的序號
            return value
        else:
            # 呼叫父類的pre_save,但不會在資料庫中增加記錄
            return super(OrderField, self).pre_save(model_instance, add)