针对“课程列表”与“课程详情”的api的写法

前端vue的项目在这里

vue项目实用笔记

表结构的设计 —— 课程、课程详细、章节

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)
   # 注意这么设计的话需要加上related_name,否则反向查询的时候会有问题 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

 

在admin中录入数据

先注册

 

创建超级用户

python manage.py createsuperuser

进入admin页面录入数据

xxx

课程列表接口与课程详情接口的写法 *****

路由的写法

由于需要进行“版本控制”,并且做了路由的分发,我们在项目的主路由中加上版本进行分发:

from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/(?P<version>\w+)/', include('api.urls')),
]

然后在api应用中写具体路由(这里用到了ViewSetMixin,注意写法):

from django.conf.urls import url,include

from api.views import course


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

    # 方式二
   # 获取所有数据用list方法 url(r'^course/$', course.CourseView.as_view({'get':'list'})), # 获取单个数据,传pk,用retrieve方法 url(r'^course/(?P<pk>\d+)/$', course.CourseView.as_view({'get':'retrieve'})), url(r'^test$', course.test), ]

序列化类

from api import models

from rest_framework import serializers

class CourseSerializer(serializers.ModelSerializer):
    """
    课程序列化
    """
   # level显示中文,用get_xxx_display方法
level = serializers.CharField(source='get_level_display')


  # 注意Meta中需要指定model与展示的字段fields——包括上面的自定义字段
class Meta: model = models.Course fields = ['id','title','course_img','level']
class CourseDetailSerializer(serializers.ModelSerializer): """ 课程详细序列化 """ # one2one/fk/choice
   # 一对一关系展示信息而不是具体的id —— 用source,注意这里用“跨表” title = serializers.CharField(source='course.title') img = serializers.CharField(source='course.course_img')
   # 注意choices用的是 get_xxx_display,这里不加括号 level
= serializers.CharField(source='course.get_level_display') # 推荐课程与章节,多对多关系展示信息而不是具体的id —— 不推荐用depth,因为depth把所有的数据都查出来了~不方便自定制 recommends = serializers.SerializerMethodField() chapter = serializers.SerializerMethodField()
  # 注意Meta中必须指定model与要展示的字段——包括上面的自定义字段
class Meta: model = models.CourseDetail fields = ['course','title','img','level','slogon','why','recommends','chapter'] 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): # 获取所有的章节 —— 自己定制返回的个数与内容
     # 这里的obj就是CourseDetail对象 —— 基于对象的连续跨表查询 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

# 继承ViewSetMixin
class CourseView(ViewSetMixin,APIView):
   # 获取所有数据用list方法!
    def list(self,request,*args,**kwargs):
        """
        课程列表接口
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        ret = {'code':1000,'data':None}

        try:
            queryset = models.Course.objects.all()
       # 所有数据,需要加 many=True ser
= CourseSerializer(instance=queryset,many=True) ret['data'] = ser.data except Exception as e: ret['code'] = 1001 ret['error'] = '获取课程失败' return Response(ret)
   # 获取单个数据用retrieve方法!
def retrieve(self,request,*args,**kwargs): """ 课程详细接口 :param request: :param args: :param kwargs: :return: """ ret = {'code': 1000, 'data': None} try: # 获取课程ID pk = kwargs.get('pk') # 课程详细对象
# 注意这里是“跨表查询” —— 正向查询:course_id obj = models.CourseDetail.objects.filter(course_id=pk).first()        # 由于是单个数据,这里不用加 many=True ser = CourseDetailSerializer(instance=obj) ret['data'] = ser.data except Exception as e: ret['code'] = 1001 ret['error'] = '获取课程失败' return Response(ret) # test —— 一对一跨表查询 def test(request,*args,**kwargs): from django.shortcuts import HttpResponse obj = models.Course.objects.filter(id=2).first() print(obj.title) print(obj.level) # print(obj.get_level_display() ) # return HttpResponse('...')

 

~~~

posted on 2019-09-17 08:49  江湖乄夜雨  阅读(233)  评论(0编辑  收藏  举报