路费项目

课程和课程详细

views.py

1.序列化类

from rest_framework import serializers
##############序列化类
class  CourseSerializers(serializers.ModelSerializer):
    class Meta:
        model=Course
        # fields=['pk','name','course_img','sub_category']
        fields='__all__'

# 序列化课程详细的类
class  CourseDetailSerializers(serializers.ModelSerializer):
    #价格策略查询,因为涉及到跨表查询,需要单独拎出来
    price_policy_dict = serializers.SerializerMethodField()
    #课程详细时间,也涉及到跨表
    coursedetail__hours = serializers.SerializerMethodField()
    teachers = serializers.SerializerMethodField()
    coursechapters = serializers.SerializerMethodField()
    questions = serializers.SerializerMethodField()
    courseoutline = serializers.SerializerMethodField()
    recommend_courses = serializers.SerializerMethodField()
    class Meta:
        model=Course
        fields=['pk','name','course_img','price_policy_dict','coursedetail__hours','teachers','coursechapters','questions','courseoutline','recommend_courses']
    # 价格策略,返回的是一个列表,里边是相关信息
    #obj代表的是当前的被查询的对象
    def get_price_policy_dict(self,obj):
        temp = []
        d = 1
        for i in obj.price_policy.all():
            # temp.append({i.valid_period,i.price})
            temp.append({d:{"valid":i.valid_period,'price':i.price,"price_id":i.pk}})
            d+=1
        return temp
    def get_coursedetail__hours(self,obj):
        return obj.coursedetail.hours
    def get_teachers(self,obj):
        temp=[]
        for item in obj.coursedetail.teachers.all():
            temp.append({'name':item.name,"image":item.image})
        return temp

    def get_coursechapters(self, obj):
        temp = []
        for item in obj.course_chapters.all():
            temp.append({item.chapter, item.name,item.summary})
        return temp
    def get_questions(self, obj):
        temp = []
        for item in obj.questions.all():
            temp.append({item.question, item.answer})
        return temp

    def get_courseoutline(self, obj):
        temp = []
        itemlist=obj.coursedetail.courseoutline_set.all().order_by('-order')
        for item in itemlist:
            temp.append({item.title, item.content})
        return temp
    def get_recommend_courses(self, obj):
        temp = []
        for item in obj.coursedetail.recommend_courses.all():
            temp.append({item.name,})
        return temp

2.视图类



#
课程详细页 class Course_s2(APIView): # authentication_classes = [MyAuthentination,] renderer_classes = [JSONRenderer,] def get(self,request,pk=None): #先判断要查询的课程是否带有pk值 #如果不带有PK的话,则表示是查询课程,显示课程列表的 if not pk: #实例化回复信息对象 ret=BaseResponse() try: #自定制分页器,实例化分页器对象 png=Pnpagenation() queryset = Course.objects.all().only('name','course_img','brief',).order_by('-id') # queryset = Course.objects.all().values('name','course_img','brief',) #对数据进行分页, queryset=png.paginate_queryset(queryset=queryset,request=request,view=self) #通过使用自定义的序列化类,对数据进行序列化, res=CourseSerializers(queryset,many=True) # print(res.data,type(res.data)) # ret.data=res.data #取出序列化的结果 res.data方法取出序列化结果 except ObjectDoesNotExist as e: ret.code=2000 ret.error='数据不存在' except Exception as e: ret.code=3000 ret.error='查询失败' # 将ret中的数据返回给前端,ret中包含状态码,数据信息,错误信息 # 因为Response有能够将字典类型的数据处理的能力,所以直接将 # 字典返回{'code': 1000, 'data': res.data, 'error': None} return Response(ret.dict) else: #当含有pk时,表示此时查询的是课程的详细信息,具体到哪一门课程了 print('进来了') ret = BaseResponse() try: queryset= Course.objects.filter(pk=pk).only('name','course_img','coursedetail__hours','coursedetail__video_brief_link').order_by('-id') print(queryset,'到这里了') res=CourseDetailSerializers(queryset,many=True) print(res.data,type(res.data)) ret.data=res.data return Response(ret.dict) except ObjectDoesNotExist as e: ret.code=2000 ret.error='数据不存在' except Exception as e: ret.code=3000 ret.error='查询失败' return Response(ret.dict)

 

 

 代码

 

跨域的

#encoding=utf-8
from django.utils.deprecation import MiddlewareMixin
class Kuayu(MiddlewareMixin):
    def process_request(self, request):
        pass
    def process_response(self, request, response):
        if request.method=='OPTIONS':
            response["Access-Control-Allow-Origin"] = 'http://localhost:8080'
            response["Access-Control-Allow-Methods"] = 'PUT'
            response["Access-Control-Allow-Credentials"] = 'True'

            return response
        else:
            response["Access-Control-Allow-Origin"]='http://localhost:8080'
            return response
View Code

 BaseResponse.py

#encoding=utf-8
#创建一个类,用于对返回数据的封装,将数据封装成字典,当使用.dict调用的时候
# 就可以返回字典形式的数据
class BaseResponse(object):


    def __init__(self,code=1000,data=None,error=None):
        self.code=code
        self.data=data
        self.error=error
    @property
    def dict(self):
        '''
        @property这样设置,在调用他的实例化对象的情境中
        通过对象名.dict就可以得到{'code': 1000, 'data': None, 'error': None}
        这种类型的数据
        :return:
        '''
        return self.__dict__
Pnpagenation.py  处理分页功能
#encoding=utf-8
#自定制的分页功能
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination
class Pnpagenation(PageNumberPagination):
    page_size = 4
    max_page_size = 10
    page_query_param = 'page'
    page_size_query_param = 'size'

 

 

 

 

数据库表代码

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

import hashlib
import datetime


# ############ 1. 课程相关 #############
class CourseCategory(models.Model):
    """课程大类, e.g 前端  后端..."""
    name = models.CharField(max_length=64, unique=True)
    def __str__(self):
        return self.name
    class Meta:
        verbose_name = "课程大类"
        verbose_name_plural = "课程大类"


class CourseSubCategory(models.Model):
    """课程子类课程子类, e.g python linux """
    category = models.ForeignKey("CourseCategory")
    name = models.CharField(max_length=64, unique=True)
    def __str__(self):
        return self.name
    class Meta:
        verbose_name = "课程子类"
        verbose_name_plural = "课程子类"


class DegreeCourse(models.Model):
    """学位课程"""
    name = models.CharField(max_length=128, unique=True)
    course_img = models.CharField(max_length=255, verbose_name="缩略图")
    brief = models.TextField(verbose_name="学位课程简介", )
    total_scholarship = models.PositiveIntegerField(verbose_name="总奖学金(贝里)", default=40000)
    mentor_compensation_bonus = models.PositiveIntegerField(verbose_name="本课程的导师辅导费用(贝里)", default=15000)
    period = models.PositiveIntegerField(verbose_name="建议学习周期(days)", default=150, help_text='为了计算学位奖学金')
    prerequisite = models.TextField(verbose_name="课程先修要求", max_length=1024)
    teachers = models.ManyToManyField("Teacher", verbose_name="课程讲师")

    # 用于GenericForeignKey反向查询, 不会生成表字段,切勿删除
    # coupon = GenericRelation("Coupon")
    # 用于GenericForeignKey反向查询,不会生成表字段,切勿删除
    degreecourse_price_policy = GenericRelation("PricePolicy")

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = "学位课程"
        verbose_name_plural = "学位课程"


class Teacher(models.Model):
    """讲师、导师表"""
    name = models.CharField(max_length=32, verbose_name='姓名')
    role_choices = ((1, '讲师'), (2, '导师'))
    role = models.SmallIntegerField(choices=role_choices, default=1)

    title = models.CharField(max_length=64, verbose_name="职位、职称")
    signature = models.CharField(max_length=255, verbose_name="导师签名", blank=True, null=True)
    image = models.CharField(max_length=128, verbose_name='头像')
    brief = models.TextField(max_length=1024, verbose_name='简介')
    def __str__(self):
        return self.name
    class Meta:
        verbose_name = "讲师、导师表"
        verbose_name_plural = "讲师、导师表"


class Scholarship(models.Model):
    """学位课程奖学金,例如:使用20%的时间学完课程,则奖励5000;使用50%的时间学完课程,则奖励2000"""
    degree_course = models.ForeignKey("DegreeCourse")
    time_percent = models.PositiveSmallIntegerField(verbose_name="奖励档位(时间百分比)", help_text="只填百分值,如80,代表80%")
    value = models.PositiveIntegerField(verbose_name="奖学金数额")

    def __str__(self):
        return self.degree_course.name

    class Meta:
        verbose_name = "奖学金"
        verbose_name_plural = "奖学金"


class Course(models.Model):
    """普通课程或学位课的模块"""
    name = models.CharField(max_length=128, unique=True, verbose_name='课程名称或学位课模块名称')
    course_img = models.CharField(max_length=255, verbose_name='课程图片')
    sub_category = models.ForeignKey("CourseSubCategory", verbose_name='课程所属类')

    course_type_choices = ((1, '付费'), (2, 'VIP专享'), (3, '学位课程'))
    course_type = models.SmallIntegerField(choices=course_type_choices)

    # 和学位课做FK,可以为  blank=True, null=True,
    degree_course = models.ForeignKey("DegreeCourse", blank=True, null=True, help_text="若是学位课程的模块,此处关联学位表")


    brief = models.TextField(verbose_name="课程概述", max_length=2048)
    level_choices = ((1, '初级'), (2, '中级'), (3, '高级'))
    level = models.SmallIntegerField(choices=level_choices, default=1)
    pub_date = models.DateField(verbose_name="发布日期", blank=True, null=True)
    period = models.PositiveIntegerField(verbose_name="建议学习周期(days)", default=7)
    order = models.IntegerField("课程顺序", help_text="从上一个课程数字往后排")
    attachment_path = models.CharField(max_length=128, verbose_name="课件路径", blank=True, null=True)
    status_choices = ((1, '上线'), (2, '下线'), (3, '预上线'))
    status = models.SmallIntegerField(choices=status_choices, default=1)

    # 用于GenericForeignKey反向查询,不会生成表字段,切勿删除
    # coupon = GenericRelation("Coupon")
    # 用于GenericForeignKey反向查询,不会生成表字段,切勿删除
    price_policy = GenericRelation("PricePolicy")
    # 用于GenericForeignKey反向查询,不会生成表字段,切勿删除
    questions = GenericRelation("OftenAskedQuestion")
    def __str__(self):
        return self.name
    class Meta:
        verbose_name = "课程"
        verbose_name_plural = "课程"




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


class CourseDetail(models.Model):
    """课程详情页内容"""
    course = models.OneToOneField("Course")
    hours = models.IntegerField("课时")
    course_slogan = models.CharField(max_length=125, blank=True, null=True, verbose_name='课程Slogan')
    video_brief_link = models.CharField(verbose_name='课程介绍', max_length=255, blank=True, null=True)
    why_study = models.TextField(verbose_name="为什么学习这门课程")
    what_to_study_brief = models.TextField(verbose_name="我将学到哪些内容")
    career_improvement = models.TextField(verbose_name="此项目如何有助于我的职业生涯")
    prerequisite = models.TextField(verbose_name="课程先修要求", max_length=1024)
    teachers = models.ManyToManyField("Teacher", verbose_name="课程讲师")
    recommend_courses = models.ManyToManyField('Course', verbose_name="推荐课程", related_name="recommend_by")
    class Meta:
        verbose_name = "课程详情"
        verbose_name_plural = "课程详情"
    def __str__(self):
        return self.course.name
class OftenAskedQuestion(models.Model):
    """课程和学位课的常见问题"""

    content_type = models.ForeignKey(ContentType, verbose_name='关联课程或学位课程表')
    object_id = models.PositiveIntegerField(verbose_name='关联课程或学位课程表中的课程ID')
    content_object = GenericForeignKey('content_type', 'object_id')

    question = models.CharField(max_length=255, verbose_name='问题')
    answer = models.TextField(max_length=1024, verbose_name='回答')

    class Meta:
        unique_together = ('content_type', 'object_id', 'question')
        verbose_name = "课程和学位课的常见问题"
        verbose_name_plural = "课程和学位课的常见问题"


class CourseOutline(models.Model):
    """课程大纲"""
    course_detail = models.ForeignKey("CourseDetail")
    title = models.CharField(max_length=128, verbose_name='大纲标题')
    content = models.TextField(max_length=1024, verbose_name='大纲内容')
    order = models.PositiveSmallIntegerField(default=1, verbose_name='大纲显示顺序')

    class Meta:
        unique_together = ('course_detail', 'title')
        verbose_name = "课程大纲"
        verbose_name_plural = "课程大纲"


class CourseChapter(models.Model):
    """课程章节"""
    course = models.ForeignKey("Course", related_name='course_chapters')
    chapter = models.SmallIntegerField(verbose_name="章节序号(第N章)", default=1)
    name = models.CharField(max_length=128, verbose_name='章节名称')
    summary = models.TextField(verbose_name="章节介绍", blank=True, null=True)
    pub_date = models.DateField(verbose_name="发布日期", auto_now_add=True)
    def __str__(self):
        return self.course.name
    class Meta:
        unique_together = ("course", 'chapter')
        verbose_name = "课程章节"
        verbose_name_plural = "课程章节"


class CourseSection(models.Model):
    """课时"""
    chapter = models.ForeignKey("CourseChapter", related_name='course_sections')
    name = models.CharField(max_length=128, verbose_name='课程名称')
    section_type_choices = ((1, '文档'), (2, '练习'), (3, '视频'))
    section_type = models.SmallIntegerField(default=3, choices=section_type_choices, verbose_name='课程类型')

    order = models.PositiveSmallIntegerField(verbose_name="课时顺序", help_text="建议每个课时之间空1至2个值,以备后续插入课时")
    section_link = models.CharField(verbose_name='课时链接', max_length=255, blank=True, null=True,
                                    help_text="若是video,填CC视频的唯一标识(如:ECC9954677D8E1079C33DC5901307461),若是文档或练习,填链接")
    video_time = models.CharField(verbose_name="视频时长(在前端显示)", blank=True, null=True, max_length=32)
    pub_date = models.DateTimeField(verbose_name="发布时间", auto_now_add=True)
    free_trail = models.BooleanField("是否可试看", default=False)

    class Meta:
        unique_together = ('chapter', 'section_link')
        verbose_name = "课时"
        verbose_name_plural = "课时"


class Homework(models.Model):
    """课程章节作业和考核"""
    chapter = models.ForeignKey("CourseChapter")
    title = models.CharField(max_length=128, verbose_name="作业题目")
    order = models.PositiveSmallIntegerField("作业顺序", help_text="同一课程的每个作业之前的order值间隔1-2个数")
    homework_type_choices = ((1, '作业'), (2, '模块通关考核'))
    homework_type = models.SmallIntegerField(choices=homework_type_choices, default=1)
    requirement = models.TextField(max_length=1024, verbose_name="作业需求")
    threshold = models.TextField(max_length=1024, verbose_name="踩分点")
    recommend_period = models.PositiveSmallIntegerField("推荐完成周期(天)", default=7, help_text='用于计算奖学金')
    scholarship_value = models.PositiveSmallIntegerField("为该作业分配的奖学金(贝里)")
    enabled = models.BooleanField(default=True, help_text="本作业如果后期不需要了,不想让学员看到,可以设置为False")
    note = models.TextField(blank=True, null=True, verbose_name='注意事项')

    class Meta:
        unique_together = ("chapter", "title")
        verbose_name = "课程章节作业和考核"
        verbose_name_plural = "课程章节作业和考核"


class PricePolicy(models.Model):
    """价格与有课程效期表"""
    content_type = models.ForeignKey(ContentType, verbose_name='关联普通课或者学位课表',related_name='x2')
    object_id = models.PositiveIntegerField(verbose_name='关联普通课或者学位课中的课程ID')
    content_object = GenericForeignKey('content_type', 'object_id')

    valid_period_choices = (
        (1, '1天'),
        (3, '3天'),
        (7, '1周'),
        (14, '2周'),
        (30, '1个月'),
        (60, '2个月'),
        (90, '3个月'),
        (180, '6个月'),
        (210, '12个月'),
        (540, '18个月'),
        (720, '24个月'),
    )
    valid_period = models.SmallIntegerField(choices=valid_period_choices, verbose_name='课程周期')
    price = models.FloatField(verbose_name='价格')

    class Meta:
        unique_together = ("content_type", 'object_id', "valid_period")
        verbose_name = "价格与有课程效期表"
        verbose_name_plural = "价格与有课程效期表"




# ############ 2. 账户相关 #############

class Account(models.Model):
    """用户账户"""
    username = models.CharField("用户名", max_length=64, unique=True)
    email = models.EmailField(verbose_name='邮箱', max_length=255, unique=True, blank=True, null=True)
    password = models.CharField(verbose_name='密码', max_length=128)
    class Meta:
        verbose_name = '账户信息'
        verbose_name_plural = "账户信息"

    def __str__(self):
        return self.username

    def save(self, *args, **kwargs):
        if not self.pk:
            m = hashlib.md5()
            m.update(self.username.encode(encoding="utf-8"))
            self.uid = m.hexdigest()
        super(Account, self).save(*args, **kwargs)



class UserAuthToken(models.Model):
    """
    用户Token表
    """
    user = models.OneToOneField(to="Account")
    token = models.CharField(max_length=40, unique=True)
    created = models.DateTimeField(auto_now_add=True)

    def save(self, *args, **kwargs):
        self.token = self.generate_key()
        self.created = datetime.datetime.utcnow()
        return super(UserAuthToken, self).save(*args, **kwargs)

    def generate_key(self):
        """根据用户名和时间生成唯一标识"""
        username = self.user.username
        now = str(datetime.datetime.now()).encode('utf-8')
        md5 = hashlib.md5(username.encode('utf-8'))
        md5.update(now)
        return md5.hexdigest()

    class Meta:
        verbose_name = '用户Token表'
        verbose_name_plural = "用户Token表"


# class Province(models.Model):
#     """
#     省份表
#     """
#     code = models.IntegerField(verbose_name="省代码", unique=True)
#     name = models.CharField(max_length=64, verbose_name="省名称", unique=True)
#
#
# class City(models.Model):
#     """
#     城市表
#     """
#     code = models.IntegerField(verbose_name="市", unique=True)
#     name = models.CharField(max_length=64, verbose_name="市名称")
#     province = models.ForeignKey("Province")


# class Industry(models.Model):
#     """
#     行业表
#     """
#     name = models.CharField(max_length=64, verbose_name="行业名称")


# class Profession(models.Model):
#     """
#     职位表,与行业表外键关联
#     """
#     name = models.CharField(max_length=64, verbose_name="职位名称")
#     industry = models.ForeignKey("Industry")


class Feedback(models.Model):
    """用户反馈表"""
    name = models.CharField(max_length=32, blank=True, null=True)
    contact = models.CharField(max_length=64, blank=True, null=True)
    feedback_type_choices = ((1, '网站优化建议'), (2, '烂!我想吐槽'), (3, '网站bug反馈'))
    feedback_type = models.SmallIntegerField(choices=feedback_type_choices)
    content = models.TextField(max_length=1024)
    date = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = '用户反馈表'
        verbose_name_plural = "用户反馈表"
    def __str__(self):
        return self.name


class Tags(models.Model):
    """标签"""
    tag_type_choices = ((1, '文章标签'), (2, '课程评价标签'), (3, '用户感兴趣技术标签'))
    tag_type = models.SmallIntegerField(choices=tag_type_choices)
    name = models.CharField(max_length=64, unique=True, db_index=True)

    def __str__(self):
        return self.name




# ############ 5. 深科技 #############
class ArticleSource(models.Model):
    """文章来源"""
    name = models.CharField(max_length=64, unique=True)


class Article(models.Model):
    """文章资讯"""
    title = models.CharField(max_length=255, unique=True, db_index=True, verbose_name="文章标题")
    source = models.ForeignKey("ArticleSource", verbose_name="来源")
    article_type_choices = ((1, '资讯'), (2, '视频'))
    article_type = models.SmallIntegerField(choices=article_type_choices, default=1)
    brief = models.TextField(max_length=512, verbose_name="摘要")
    head_img = models.CharField(max_length=255, verbose_name='文章图片')
    content = models.TextField(verbose_name="文章正文")

    pub_date = models.DateTimeField(verbose_name="上架日期")
    offline_date = models.DateTimeField(verbose_name="下架日期")
    status_choices = ((1, '在线'), (2, '下线'))
    status = models.SmallIntegerField(choices=status_choices, default=1, verbose_name="状态")
    order = models.SmallIntegerField(default=0, verbose_name="权重", help_text="文章想置顶,可以把数字调大,不要超过1000")

    vid = models.CharField(max_length=128, verbose_name="视频VID", help_text="文章类型是视频, 则需要添加视频VID", blank=True, null=True)
    comment_num = models.SmallIntegerField(default=0, verbose_name="评论数")
    agree_num = models.SmallIntegerField(default=0, verbose_name="点赞数")
    view_num = models.SmallIntegerField(default=0, verbose_name="观看数")
    collect_num = models.SmallIntegerField(default=0, verbose_name="收藏数")

    tags = models.ManyToManyField("Tags", blank=True, verbose_name="标签")
    date = models.DateTimeField(auto_now_add=True, verbose_name="创建日期")

    position_choices = ((1, '信息流'), (2, 'banner大图'), (3, 'banner小图'))
    position = models.SmallIntegerField(choices=position_choices, default=1, verbose_name="位置")
    comment = GenericRelation("Comment", help_text='用于GenericForeignKey反向查询,不会生成表字段,切勿删除')

    class Meta:
        verbose_name = '文章资讯'
        verbose_name_plural = "文章资讯"

    def __str__(self):
        return self.title

class Collection(models.Model):
    """收藏"""
    account = models.ForeignKey("Account", verbose_name='用户')

    content_type = models.ForeignKey(ContentType, verbose_name='文章或视频表')
    object_id = models.PositiveIntegerField(verbose_name='文章或者视频ID')
    content_object = GenericForeignKey('content_type', 'object_id')

    date = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('content_type', 'object_id', 'account')
        verbose_name = '收藏'
        verbose_name_plural = "收藏"

class Comment(models.Model):
    """通用的评论表"""
    account = models.ForeignKey("Account", verbose_name="用户")

    content_type = models.ForeignKey(ContentType, blank=True, null=True, verbose_name="文章或视频表")
    object_id = models.PositiveIntegerField(blank=True, null=True, verbose_name='文章或者视频ID')
    content_object = GenericForeignKey('content_type', 'object_id')

    p_node = models.ForeignKey("self", blank=True, null=True, verbose_name="父级评论")
    content = models.TextField(max_length=1024)

    disagree_number = models.IntegerField(default=0, verbose_name="")
    agree_number = models.IntegerField(default=0, verbose_name="赞同数")
    date = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = '通用的评论表'
        verbose_name_plural = "通用的评论表"
View Code

admin.py中进行注册表

from django.contrib import admin

# Register your models here.
from django.contrib.admin import ModelAdmin
from .models import *
admin.site.register(CourseCategory)
admin.site.register(CourseSubCategory)
admin.site.register(DegreeCourse)
admin.site.register(Teacher)
admin.site.register(Scholarship)
class CourseConfig(ModelAdmin):
    list_display = ['pk','name','course_type','degree_course']
admin.site.register(Course,CourseConfig)
admin.site.register(CourseDetail)
admin.site.register(OftenAskedQuestion)
admin.site.register(CourseOutline)
admin.site.register(CourseChapter)
admin.site.register(CourseSection)
admin.site.register(Homework)
admin.site.register(PricePolicy)
admin.site.register(Account)
admin.site.register(UserAuthToken)
# admin.site.register(Province)
# admin.site.register(City)
# admin.site.register(Industry)
# admin.site.register(Profession)
admin.site.register(Feedback)
admin.site.register(Tags)
admin.site.register(ArticleSource)
admin.site.register(Article)
admin.site.register(Collection)
admin.site.register(Comment)
View Code

 

 

 

 https://pan.baidu.com/s/1qsNGrX8M1s2lTAvp1Z2uEQ

 

posted on 2018-06-13 11:17  王大拿  阅读(146)  评论(0)    收藏  举报

导航