1. 建模
from django.db import models from django.contrib.contenttypes.fields import GenericForeignKey,GenericRelation from django.contrib.contenttypes.models import ContentType # Create your models here. class CourseCategory(models.Model): """ 课程大类, e.g 前端 后端... """ name =models.CharField(max_length=64,unique=True) def __str__(self): return "%s" %self.name class Meta: verbose_name_plural ="01.课程大纲" class CourseSubCategory(models.Model): # 课程子类,e.g python linux category =models.ForeignKey("CourseCategory") name =models.CharField(max_length=64,unique=True) def __str__(self): return "%s" % self.name class Meta: verbose_name_plural="02.课程子类" 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)#为了计算学位奖学金 prerequisite=models.TextField(verbose_name="课程先修要求",max_length=1024) teachers = models.ManyToManyField("Teacher",verbose_name="课程讲师") #用于GenericForeignKey反向查询,不会生成表字段,切勿删除 # coupon =GenericRelation("Coupon") #用于GenricForeignKey反向查询,不会产生字段,切勿删除. degreecourse_price_policy =GenericRelation("PricePolicy") def __str__(self): return self.name class Meta: verbose_name_plural= "03.学位课" class Teacher(models.Model): #讲师、导师表 name =models.CharField(max_length=32) role_choices =((0,"讲师"),(1,"导师")) role = models.SmallIntegerField(choices=role_choices,default=0 ) title =models.CharField(max_length=64,verbose_name="职位,职称") signature= models.CharField(max_length=255,help_text="导师签名",blank=True,null=True) image =models.CharField(max_length=128) brief =models.TextField(max_length=1024) def __str__(self): return self.name class Meta: verbose_name_plural="04.导师或讲师" class Scholarship(models.Model): #学位课程奖学金 degree_course=models.ForeignKey("DegreeCourse") time_percent =models.PositiveIntegerField(verbose_name="奖励档位(时间百分比)",help_text="只填百分之,如80,代表80%") value =models.PositiveIntegerField(verbose_name="奖学金数额") def __str__(self): return "%s:%s"%(self.degree_course,self.value) class Meta: verbose_name_plural ="05.学位课奖学金" class Course(models.Model): #专业课程 name = models.CharField(max_length=128,unique=True) course_img =models.CharField(max_length=255) sub_category =models.ForeignKey("CourseSubCategory") course_type_choice =((0,"付费"),(1,"vip专享"),(2,"学位课程")) course_type =models.SmallIntegerField(choices=course_type_choice) degree_course =models.ForeignKey("DegreeCourse",blank=True,null= True,help_text="若是学位课程,此处关联学位表") brief =models.TextField(verbose_name="课程概述",max_length=2048) level_choices =((0,"初级"),(1,"中级"),(2,"高级")) 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_patch =models.CharField(max_length=128,verbose_name="课程路径",blank=True,null=True) status_choice =((0,"上线"),(1,"下线"),(2,"预上线")) template_id=models.SmallIntegerField(choices=status_choice,default=0 ) # coupon =GenericRelation("Coupon") #用于GenericForeignKey反向查询,不会生成表字段,切勿删除. price_policy=GenericRelation("PricePolicy") asked_question =GenericRelation("OftenAskedQuestion") def __str__(self): return "%s(%s)"%(self.name ,self.get_course_type_display()) def save(self, *args ,**kwargs): if self.course_type==2 : if not self.degree_course: raise ValueError("学位课程必须关联对应的学位表") super(Course, self).save(*args,**kwargs) class Meta: verbose_name_plural="06.专题课程或学位课程模块" class CourseDetail(models.Model): """课程详情页内容""" course = models.OneToOneField("Course") hours = models.IntegerField("课时") course_slogan = models.CharField(max_length=125, blank=True, null=True) 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) recommend_courses = models.ManyToManyField("Course", related_name="recommend_by", blank=True) teachers = models.ManyToManyField("Teacher", verbose_name="课程讲师") def __str__(self): return "%s" % self.course class Meta: verbose_name_plural = "07.课程或学位模块详细" class OftenAskedQuestion(models.Model): """常见问题""" content_type = models.ForeignKey(ContentType, limit_choices_to={'model__contains': 'course'}) # 关联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 "%s-%s" % (self.content_object, self.question) class Meta: unique_together = ('content_type', 'object_id', 'question') verbose_name_plural = "08. 常见问题" class CourseOutline(models.Model): """课程大纲""" course_detail = models.ForeignKey("CourseDetail") title = models.CharField(max_length=128) # 前端显示顺序 order = models.PositiveSmallIntegerField(default=1) content = models.TextField("内容", max_length=2048) def __str__(self): return "%s" % self.title class Meta: unique_together = ('course_detail', 'title') verbose_name_plural = "09. 课程大纲" class CourseChapter(models.Model): """课程章节""" course = models.ForeignKey("Course", related_name='coursechapters') chapter = models.SmallIntegerField(verbose_name="第几章", default=1) name = models.CharField(max_length=128) summary = models.TextField(verbose_name="章节介绍", blank=True, null=True) pub_date = models.DateField(verbose_name="发布日期", auto_now_add=True) class Meta: unique_together = ("course", 'chapter') verbose_name_plural = "10. 课程章节" def __str__(self): return "%s:(第%s章)%s" % (self.course, self.chapter, self.name) class CourseSection(models.Model): """课时目录""" chapter = models.ForeignKey("CourseChapter", related_name='coursesections') name = models.CharField(max_length=128) order = models.PositiveSmallIntegerField(verbose_name="课时排序", help_text="建议每个课时之间空1至2个值,以备后续插入课时") section_type_choices = ((0, '文档'), (1, '练习'), (2, '视频')) section_type = models.SmallIntegerField(default=2, choices=section_type_choices) section_link = models.CharField(max_length=255, blank=True, null=True, help_text="若是video,填vid,若是文档,填link") 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_plural = "11. 课时" def __str__(self): return "%s-%s" % (self.chapter, self.name) 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 = ((0, '作业'), (1, '模块通关考核')) homework_type = models.SmallIntegerField(choices=homework_type_choices, default=0) requirement = models.TextField(max_length=1024, verbose_name="作业需求") threshold = models.TextField(max_length=1024, verbose_name="踩分点") recommend_period = models.PositiveSmallIntegerField("推荐完成周期(天)", default=7) scholarship_value = models.PositiveSmallIntegerField("为该作业分配的奖学金(贝里)") note = models.TextField(blank=True, null=True) enabled = models.BooleanField(default=True, help_text="本作业如果后期不需要了,不想让学员看到,可以设置为False") class Meta: unique_together = ("chapter", "title") verbose_name_plural = "12. 章节作业" def __str__(self): return "%s - %s" % (self.chapter, self.title) class PricePolicy(models.Model): """价格与有课程效期表""" content_type = models.ForeignKey(ContentType) # 关联course or degree_course object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') # course = models.ForeignKey("Course") 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) price = models.FloatField() class Meta: unique_together = ("content_type", 'object_id', "valid_period") verbose_name_plural = "15. 价格策略" def __str__(self): return "%s(%s)%s" % (self.content_object, self.get_valid_period_display(), self.price)
2. settings设置
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', 'api.apps.ApiConfig', "rest_framework" ]
3. url 路径
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^api/(?P<version>\w+)/', include("api.api_url")), ]
from api.views import course urlpatterns=[ url(r'courses/',course.CourseView.as_view()), # url(r'courses/(?P<pk>\d+)',course.CourseView.as_view()) ]
4. 在admin文件中注册
from django.contrib import admin # Register your models here. from api.models import * admin.site.register(CourseCategory) admin.site.register(CourseSubCategory) admin.site.register(DegreeCourse) admin.site.register(Teacher) admin.site.register(Scholarship) admin.site.register(Course) 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)
5. views 逻辑函数 方法一、json.dumps
from django.shortcuts import HttpResponse from rest_framework.views import APIView import json from api import models class CourseView(APIView): def get(self,request,*args,**kwargs): #方式一: course_list =list(models.Course.objects.all().values("id","name")) return HttpResponse(json.dumps(course_list,ensure_ascii=False))
输出结果:
6. views逻辑函数 方法二、 序列化
创建序列化的文档 course
from rest_framework import serializers class CourseSerializer(serializers.Serializer): id = serializers.IntegerField() name =serializers.CharField()
view视图
from django.shortcuts import HttpResponse from rest_framework.views import APIView from api.serializers.course import CourseSerializer from api import models class CourseView(APIView): def get(self,request,*args,**kwargs): # 方法二: course_list =models.Course.objects.all() ser =CourseSerializer(instance=course_list,many=True) return HttpResponse(ser.data)
输出结果
第三种方法(查询所有Course的API)
from rest_framework.views import APIView from rest_framework.versioning import URLPathVersioning from api.serializers.course import CourseSerializer from api import models from rest_framework.response import Response class CourseView(APIView): def get(self,request,*args,**kwargs): course_list =models.Course.objects.all() ser = CourseSerializer(instance=course_list,many =True) return Response(ser.data)
输出结果:
最后一种方法是 ModelViewSet,但是我们暂时不要用, 那种方式是最简单的,所有的功能都在源码里封装好了,初学者使用APIview进行训练。
查询某个Course的API