路飞项目实践

01-重要的表结构

课程的表结构(12张)

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericRelation
from django.contrib.contenttypes.fields import GenericForeignKey

__all__ = ["Category", "Course", "CourseDetail", "Teacher", "DegreeCourse",
           "CourseChapter", "CourseSection", "PricePolicy", "OftenAskedQuestion", "Comment",
           "Account", "CourseOutline"]


class Category(models.Model):
    """课程分类"""
    title = models.CharField(max_length=32, unique=True, verbose_name="课程分类")

    def __str__(self):
        return self.title

    class Meta:
        db_table = "01-课程分类"  # 上线删除
        verbose_name_plural = verbose_name = "01-课程分类"


class Course(models.Model):
    """课程表"""
    COURSE_TYPE_CHOICES = ((0, "付费"), (1, "vip专享"), (2, "学位课程"))

    course_type = models.SmallIntegerField(choices=COURSE_TYPE_CHOICES)
    course_img = models.ImageField(upload_to="", verbose_name="课程图片", blank=True, null=True)
    title = models.CharField(max_length=128, unique=128, verbose_name="课程名称")

    category = models.ForeignKey(to="Category", verbose_name="课程的分类")
    degree_course = models.ForeignKey(to="DegreeCourse", null=True, blank=True, help_text="如果是学位课程, 必须关联学位表")

    LEVEL_CHOICES = ((0, "初级"), (1, "中级"), (3, "高级"))
    STATUS_CHOICES = ((0, "上线"), (1, "下线"), (2, "预上线"))
    brief = models.CharField(verbose_name="课程简介", max_length=1024)
    level = models.SmallIntegerField(choices=LEVEL_CHOICES, default=1)
    status = models.SmallIntegerField(choices=STATUS_CHOICES, default=0)
    pub_date = models.DateField(verbose_name="发布日期", blank=True, null=True)

    order = models.IntegerField("课程顺序", help_text="从上一个数据往后排")
    study_num = models.IntegerField(verbose_name="学习人数", help_text="只要有人购买, 订单表加入数据的同时给这个字段+1")

    # 用户反向查找查询, 不生成字段
    price_policy = GenericRelation("PricePolicy")
    often_ask_qeestions = GenericRelation("OftenAskedQuestion")
    course_comments = GenericRelation("Comment")

    def save(self, *args, **kwargs):
        if self.course_type == 2:
            if not self.degree_course:
                raise ValueError("学位课程必须关联学位课程表")
        super(Course, self).save(*args, **kwargs)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name_plural = verbose_name = "02-课程表"
        db_table = "02-课程表"


class CourseDetail(models.Model):
    """课程详细表"""
    hourse = models.IntegerField(verbose_name="课时", default=7)
    why_study = models.TextField(verbose_name="为什么学习这门课程")
    summary = models.TextField(max_length=2048, verbose_name="课程概述")
    what_to_study_brief = models.TextField(verbose_name="我将学到什么内容")
    vido_brief_link = models.CharField(max_length=255, blank=True, null=True)
    prerequisite = models.TextField(verbose_name="课程先修要求", max_length=1204)
    career_improvement = models.TextField(verbose_name="此项目如何有助于我的职业生涯")

    course = models.OneToOneField(to="Course")
    recommend_courses = models.ManyToManyField("Course", related_name="recommend_by", blank=True)
    teachers = models.ManyToManyField("Teacher", verbose_name="课程讲师")

    def __str__(self):
        return self.course.title

    class Meta:
        verbose_name_plural = verbose_name = "03-课程详细表"
        db_table = "03-课程详细表"


class Teacher(models.Model):
    """讲师表"""
    name = models.CharField(max_length=32, verbose_name="讲师名字")
    brief = models.TextField(max_length=1024, verbose_name="讲师介绍")

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = verbose_name = "04-讲师表"
        db_table = "04-讲师表"


class DegreeCourse(models.Model):
    """
    字段大体跟课程表相同, 哪些不同根据业务逻辑去区分
    """
    title = models.CharField(verbose_name="学位课程", max_length=32)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name_plural = verbose_name = "05-学位课程"
        db_table = "05-学位课程"


class CourseChapter(models.Model):
    """课程章节表"""
    title = models.CharField(max_length=32, verbose_name="课程章节名称")

    course = models.ForeignKey(to="Course", related_name="course_chapters")
    chapter = models.SmallIntegerField(default=1, verbose_name="第几章")

    def __str__(self):
        return self.title

    class Meta:
        verbose_name_plural = verbose_name = "06-课程章节表"
        db_table = "06-课程章节表"


class CourseSection(models.Model):
    """课时表"""
    chapter = models.ForeignKey(to="CourseChapter", related_name="course_sections")
    title = models.CharField(max_length=32, verbose_name="课时")
    section_order = models.SmallIntegerField(verbose_name="课时安排", help_text="建议每个课时之间空1至两个值, 以备后续插入课时")
    section_type_choices = ((0, "文档"), (1, "练习"), (2, "视频"))
    section_link = models.CharField(max_length=255, blank=True, null=True, help_text="若是video, 填vid, 若是文档, 填link")

    def course_chapter(self):
        return self.chapter.chapter

    def course_name(self):
        return self.chapter.course.title

    class Meta:
        verbose_name_plural = verbose_name = "07-课程课时表"
        db_table = "07-课程课时表"
        unique_together = ("chapter", "section_link")


class PricePolicy(models.Model):
    """价格策略表"""
    content_type = models.ForeignKey(ContentType)  # 关联course or degree_course
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey("content_type", "object_id")

    valid_period_choices = (
        (1, "1天"), (3, "3天"),
        (7, "1周"), (14, "2周"),
        (30, "1个月"), (60, "2个月"),
        (90, "3个月"), (120, "4个月"),
        (180, "6个月"), (210, "12个月"),
        (540, "18个月"), (720, "24个月"),
        (722, "24个月"), (723, "24个月"),
    )
    valid_period = models.SmallIntegerField(choices=valid_period_choices)
    price = models.FloatField()

    def __str__(self):
        return "{}({}){}".format(self.content_object, self.get_valid_period_display(), self.price)

    class Meta:
        verbose_name_plural = verbose_name = "08-价格策略表"
        db_table = "08-价格策略表"
        unique_together = ("content_type", "object_id", "valid_period")


class OftenAskedQuestion(models.Model):
    """常见问题"""
    content_type = models.ForeignKey(ContentType)  # 关联course or degree_course
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey("content_type", "object_id")

    question = models.CharField(max_length=255)
    answer = models.TextField(max_length=1024)

    def __str__(self):
        return "{}-{}".format(self.content_object, self.question)

    class Meta:
        verbose_name_plural = verbose_name = "09-常见问题"
        db_table = "09-常见问题"
        unique_together = ("content_type", "object_id", "question")


class Comment(models.Model):
    """通用评论表"""
    content_type = models.ForeignKey(ContentType, blank=True, null=True)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey("content_type", "object_id")

    content = models.TextField(max_length=1024, verbose_name="评论内容")
    account = models.ForeignKey("Account", verbose_name="会员名")
    date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.content

    class Meta:
        verbose_name_plural = verbose_name = "10-评论表"
        db_table = "10-通用评论表"


class Account(models.Model):
    """账号信息"""
    username = models.CharField(max_length=32, verbose_name="用户姓名")

    def __str__(self):
        return self.username

    class Meta:
        verbose_name_plural = verbose_name = "11-用户表"
        db_table = "11-用户表"


class CourseOutline(models.Model):
    """课程大纲"""
    course_detail = models.ForeignKey(to="CourseDetail", verbose_name="课程详细", related_name="course_outline")
    title = models.CharField(max_length=128)
    order = models.PositiveIntegerField(default=1)  # 前端显示顺序

    content = models.TextField("内容", max_length=2048)

    def __str__(self):
        return "{}".format(self.title)

    class Meta:
        verbose_name_plural = verbose_name = "12-课程大纲"
        db_table = "12-课程大纲"
        unique_together = ("course_detail", "title")
表结构(课程相关)

接口的编写

import uuid

from rest_framework.views import APIView
from rest_framework.response import Response


from . import models
from .serializers import CourseCategorySerializer
from .serializers import CourseSerializer
from .serializers import CourseDetailSerializer
from .serializers import CourseChapterSerializer
from .serializers import CourseCommentSerializer
from .serializers import UserSerializer
from course.models import Account
# 导入BaseResponse
from utils.base_response import BaseResponse
# 认证
from utils.authentications import UserAuthentication


class CourseCategory(APIView):
    """课程分类"""

    def get(self, request):
        queryset = models.Category.objects.all()
        ser_obj = CourseCategorySerializer(queryset, many=True)
        return Response(ser_obj.data)


class Course(APIView):
    """课程"""

    def get(self, request):
        cartegory_id = request.query_params.get("category", "0")
        if cartegory_id == "0":
            queryset = models.Course.objects.all().order_by("-order")
        else:
            queryset = models.Course.objects.filter(category_id=cartegory_id).order_by("-order")

        ser_obj = CourseSerializer(queryset, many=True)
        return Response(ser_obj.data)


class CourseDetailView(APIView):
    """课程详细页面"""

    def get(self, request, pk):
        course_detail_obj = models.CourseDetail.objects.filter(course_id=pk).first()
        if not course_detail_obj:
            return Response({"code": 1001, "errors": "不存在这门课程"})
        ser_obj = CourseDetailSerializer(course_detail_obj)
        return Response(ser_obj.data)


class CourseChapter(APIView):
    """课程章节"""

    def get(self, request, pk):
        queryset = models.CourseChapter.objects.filter(course_id=pk)
        ser_obj = CourseChapterSerializer(queryset, many=True)
        return Response(ser_obj.data)


class CourseContentView(APIView):
    """课程评论"""

    def get(self, request):
        queryset = models.Comment.objects.all()
        ser_obj = CourseCommentSerializer(queryset, many=True)
        return Response(ser_obj.data)
课程接口

序列化器

import hashlib

from rest_framework import serializers

from . import models


class CourseCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Category
        fields = ["id", "title"]


class CourseSerializer(serializers.ModelSerializer):
    level = serializers.CharField(source="get_level_display")
    price_policy = serializers.SerializerMethodField()

    def get_price_policy(self, obj):
        print(obj.price_policy)
        for price in obj.price_policy.all():
            return price.price

    class Meta:
        model = models.Course
        fields = ["id", "title", "course_img",
                  "category", "level", "study_num",
                  "price_policy", "brief"]


class CourseDetailSerializer(serializers.ModelSerializer):
    level = serializers.CharField(source="course.get_level_display")
    study_num = serializers.IntegerField(source="course.study_num")

    price_policy = serializers.SerializerMethodField()
    course_outline = serializers.SerializerMethodField()
    recommend_courses = serializers.SerializerMethodField()
    teachers = serializers.SerializerMethodField()

    def get_price_policy(self, obj):
        return [{"id": price_obj.id, "valid_price_display": price_obj.get_valid_period_display(),
                 "price": price_obj.price} for price_obj in obj.course.price_policy.all()]

    def get_course_outline(self, obj):
        outlines = obj.course_outline.all().order_by("order")
        return [{"title": outline.title, "content": outline.content} for outline in outlines]

    def get_recommend_courses(self, obj):
        return [{"id": item.id, "title": item.title} for item in obj.recommend_courses.all()]

    def get_teachers(self, obj):
        return [{"id": item.id, "name": item.name} for item in obj.teachers.all()]

    class Meta:
        model = models.CourseDetail
        fields = ["id", "summary", "hourse", "level", "study_num",
                  "price_policy", "why_study", "what_to_study_brief",
                  "course_outline", "career_improvement", "prerequisite",
                  "recommend_courses", "teachers"]


class CourseChapterSerializer(serializers.ModelSerializer):
    sections = serializers.SerializerMethodField()

    def get_sections(self, obj):
        sections = obj.course_sections.all().order_by("section_order")
        print(sections)
        return [{"id": item.id, "title": item.title} for item in sections]

    class Meta:
        model = models.CourseChapter
        fields = ["id", "title", "chapter", "course", "sections"]


class CourseCommentSerializer(serializers.ModelSerializer):
    account = serializers.CharField(source="account.username")

    class Meta:
        model = models.Comment
        fields = ["id", "account", "content", "date"]
序列化

 

posted @ 2018-11-09 17:28  猴里吧唧  阅读(93)  评论(0)    收藏  举报