路飞学城项目-课程模块

###############     课程模块    ################

课程模块需求
1,给前端返回所有的课程列表,
2,给前端返回单个课程的课程详情,
这两个都是get请求,如果要实现在一个类里面,就可以继承ViewSetMixin,
然后url的as_view就支持传递字典参数了,
然后覆盖list方法和retrieve方法,用来获取所有课程和获取单个课程

序列化的注意点
1,课程表和课程详细表是一对一的,一对一怎么获取,
2,怎么把choice变成汉字
3,外键关联怎么反向查找,
4,多对多的怎么获取,

理解了这几个情况你就都知道了,这样即使有1千个表,也跑不出这个范围,
这样你对视图,对路由,对序列化都有了更加深刻的认识了,

###############     表结构    ################

from django.db import models

class Course(models.Model):
    """
    课程表
    """
    title = models.CharField(verbose_name='课程名称',max_length=32)
    course_img = models.CharField(verbose_name='课程图片',max_length=64)
    level_choices = (
        (1,'初级'),
        (2,'中级'),
        (3,'高级'),
    )
    level = models.IntegerField(verbose_name='课程难易程度',choices=level_choices,default=1)

    def __str__(self):
        return self.title

class CourseDetail(models.Model):
    """
    课程详细
    """
    course = models.OneToOneField(to='Course')
    slogon = models.CharField(verbose_name='口号',max_length=255)
    why = models.CharField(verbose_name='为什么要学?',max_length=255)
    recommend_courses = models.ManyToManyField(verbose_name='推荐课程',to='Course',related_name='rc')

    def __str__(self):
        return "课程详细:"+self.course.title

class Chapter(models.Model):
    """
    章节,章节和课程是一对多的,一个课程可以有很多的章节,
    """
    num =  models.IntegerField(verbose_name='章节')
    name = models.CharField(verbose_name='章节名称',max_length=32)
    course = models.ForeignKey(verbose_name='所属课程',to='Course')

    def __str__(self):
        return self.name

###############    序列化    ################

from api import models

from rest_framework import serializers

class CourseSerializer(serializers.ModelSerializer):
    """
    课程序列化
    """
    level = serializers.CharField(source='get_level_display')
    class Meta:
        model = models.Course
        fields = ['id','title','course_img','level']


class CourseDetailSerializer(serializers.ModelSerializer):
    """
    课程详细序列化
    """
    # one2one/fk/choice,跨表使用source就可以实现了,
    title = serializers.CharField(source='course.title')
    course_img = serializers.CharField(source='course.course_img')
    level = serializers.CharField(source='course.get_level_display')
    # 上面是自定义字段,后面的source是和哪一个表的哪一个字段进行绑定,
    # 这样下面的返回的字段就很多了,
    # 这就是可以实现跨表返回数据,
    # get_level_display这一句,可以实现不是只拿一个数字,而是数字代表的汉字,
    # 注意,一定把字段放到中间,


    # m2m
    recommends = serializers.SerializerMethodField()
    # SerializerMethodField,写了这个,需要在下面写一个函数,
    # 这是拿推荐课程,注意:这种多对多的不能使用source了,
    chapter = serializers.SerializerMethodField()
    # 这是拿章节,


    class Meta:
        model = models.CourseDetail
        fields = ['course','title','img','level','slogon','why','recommends','chapter']
        # depth = 1 ,就是往下找两层,有一对多和对多就会把对应的数据拿到,但是显示的数据太多了,所以我们一般不这么用,


    def get_recommends(self,obj):  # obj就是CourseDetail
        # 获取推荐的所有课程
        queryset = obj.recommend_courses.all()

        return [{'id':row.id,'title':row.title} for row in queryset]

    def get_chapter(self,obj):
        # 获取推荐的所有课程
        queryset = obj.course.chapter_set.all()  # 这种就是反向查找,

        return [{'id':row.id,'name':row.name} for row in queryset]

###############     视图    ################

from rest_framework.views import APIView
from rest_framework.response import Response
from api import models
from rest_framework.viewsets import GenericViewSet,ViewSetMixin
from api.serializers.course import CourseSerializer,CourseDetailSerializer
from rest_framework.throttling import SimpleRateThrottle
from api.auth.auth import LuffyAuth


class CourseView(ViewSetMixin,APIView):

    def list(self,request,*args,**kwargs):
        """
        课程列表接口
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        ret = {'code':1000,'data':None}

        try:
            queryset = models.Course.objects.all()
            ser = CourseSerializer(instance=queryset,many=True)
            ret['data'] = ser.data
            print(ret)
        except Exception as e:
            ret['code'] = 1001
            ret['error'] = '获取课程失败'

        return Response(ret)

    def retrieve(self,request,*args,**kwargs):
        """
        课程详细接口
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        ret = {'code': 1000, 'data': None}

        try:
            # 课程ID=2
            pk = kwargs.get('pk')

            # 课程详细对象
            obj = models.CourseDetail.objects.filter(course_id=pk).first()

            ser = CourseDetailSerializer(instance=obj,many=False)

            ret['data'] = ser.data

        except Exception as e:
            ret['code'] = 1001
            ret['error'] = '获取课程失败'

        return Response(ret)

###############    路由    ################

from django.conf.urls import url,include

from api.views import course
from api.views import account


urlpatterns = [
    # 方式一
    # url(r'^course/$', course.CourseView.as_view()),
    # url(r'^course/(?P<pk>\d+)/$', course.CourseView.as_view()),

    # 方式二
    url(r'^course/$', course.CourseView.as_view({'get':'list'})),
    url(r'^course/(?P<pk>\d+)/$', course.CourseView.as_view({'get':'retrieve'})),
]

###############     表结构    ################

###############     表结构    ################

猜你喜欢

转载自www.cnblogs.com/andy0816/p/12301990.html