06-07 ContentType组件 - 图1


一 项目背景

路飞学成项目,有课程,学位课(不同的课程字段不一样),价格策略
问题,1 如何设计表结构,来表示这种规则
  2 为专题课,添加三个价格策略
3 查询所有价格策略,并且显示对应的课程名称
4 通过课程id,获取课程信息和价格策略

二 版本一

一个课程表,包含学位课和专题课,一个价格策略表,一对多关联
06-07 ContentType组件 - 图2

三 版本二

学位课表,专题课表,装逼课表,价格策略表(在价格策略课表中加入多个FK跟课程表做关联):后期再加其它课程,可维护性差
06-07 ContentType组件 - 图3

四 最终版(使用ContentType)

通过Django提供的ContentType表,来构建
06-07 ContentType组件 - 图4
models层创建:

  1. from django.db import models
  2. from django.contrib.contenttypes.models import ContentType
  3. from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
  4. class Course(models.Model):
  5. title = models.CharField(max_length=32)
  6. # 不会在数据库中生成字段,只用于数据库操作
  7. # policy = GenericRelation('PricePolicy',object_id_field='object_id',content_type_field='contentType')
  8. class DegreeCourse(models.Model):
  9. title = models.CharField(max_length=32)
  10. class PricePolicy(models.Model):
  11. # 跟ContentType表做外键关联
  12. contentType = models.ForeignKey(to=ContentType)
  13. # 正数
  14. object_id = models.PositiveIntegerField()
  15. # 引入一个字段,不会在数据库中创建,只用来做数据库操作
  16. # content_obj = GenericForeignKey('contentType', 'object_id')
  17. period = models.CharField(max_length=32)
  18. price = models.FloatField()

views层:

  1. from app01 import models
  2. def test(request):
  3. import json
  4. # 方式一插入价格规则
  5. # ret=models.ContentType.objects.filter(model='course').first()
  6. # course=models.Course.objects.filter(pk=1).first()
  7. # print(ret.id)
  8. # models.PricePolicy.objects.create(period='30',price=100,object_id=course.id,contentType_id=ret.id)
  9. # 方式二插入价格规则
  10. # course=models.Course.objects.filter(pk=1).first()
  11. # # content_obj=course 会自动的把课程id放到object_id上,并且去ContentType表中查询课程表的id,放到contentType上
  12. # models.PricePolicy.objects.create(period='60',price=800,content_obj=course)
  13. # 增加学位课,价格规则
  14. # degreecourse = models.DegreeCourse.objects.filter(pk=1).first()
  15. # models.PricePolicy.objects.create(period='60', price=800, content_obj=degreecourse)
  16. # 查询所有价格策略,并且显示对应的课程名称
  17. # ret=models.PricePolicy.objects.all()
  18. # for i in ret:
  19. # print(i.price)
  20. # print(i.period)
  21. # # content_obj 就是代指关联的课程,或者学位课程的那个对象
  22. # print(type(i.content_obj))
  23. # print(i.content_obj.title)
  24. # 通过课程id,获取课程信息和价格策略
  25. course=models.Course.objects.filter(pk=1).first()
  26. print(course.policy.all())
  27. return render(request,'test.html')