路飞学城项目-课程模块
############### 课程模块 ################
课程模块需求 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'})), ]
############### 表结构 ################
############### 表结构 ################
技术改变命运