第十六章 Django框架——ContentType组件
一、ContentType应用场景
二、ContentType组件使用
一、ContentType应用场景
需求:现在学校有专题课、试听课、学位课三类课程,三种课程有不同的价格策略,请设计表结构。
设计方案一:
一个课程表,包含学位课和专题课,一个价格策略表,一对多关联
设计方案二:
学位课表,专题课表,试听课表,价格策略表(在价格策略课表中加入多个FK跟课程表做关联):后期再加其它课程,可维护性差
二、ContentType组件使用
设计方案三:
通过Django提供的ContentType表,来构建关联
contenttype表位置:
contenttype表无需创建,生成数据库时自动创建
这些是我们刚才创建的表
导入模块:
# models.py内使用 from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
实现如下需求:
1.为专题课,添加三个价格策略
urls.py
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^test/',views.addPrice) ]
views.py
from django.shortcuts import * from app01.models import * # Create your views here. def addPrice(request): # 为django专题课,添加三个价格策略 course = Course.objects.filter(pk=1).first() # content = ContentType.objects.filter(model='course').first() # PricePolicy.objects.create(period=1,price=0,object_id=course.pk,content_type_id=content.pk) # PricePolicy.objects.create(period=3,price=49,object_id=course.pk,content_type_id=content.pk) # PricePolicy.objects.create(period=6,price=99,object_id=course.pk,content_type_id=content.pk) # 这一句话与上面四行意思相同,节约代码 PricePolicy.objects.create(period=12,price=300,content_obj=course)
# 为python全栈开发学位课,加一个价格策略
degree = DegreeCourse.objects.first(pk=1).first()
PricePolicy.objects.create(period=5,price=18000,content_type=degree)
return HttpResponse('ok')
models.py
from django.db import models # Create your models here. from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation class Course(models.Model): title = models.CharField(max_length=32) class DegreeCourse(models.Model): title = models.CharField(max_length=32) class PricePolicy(models.Model): period = models.IntegerField() price = models.PositiveIntegerField() content_type = models.ForeignKey(to=ContentType,null=True) # GenericForeignKey不会在数据库生成字段,只用于查询和插入 object_id = GenericForeignKey('content_type','object_id')
2.查询所有价格策略,并且显示对应的课程名称
urls.py
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^test/',views.addPrice) ]
views.py
from django.shortcuts import * from app01.models import * # Create your views here. def addPrice(request): # 查询所有价格策略,并且显示对应的课程名称 ret = PricePolicy.objects.all() for price in ret : print(price.content_obj.title) return HttpResponse('ok')
models.py
from django.db import models # Create your models here. from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation class Course(models.Model): title = models.CharField(max_length=32) class DegreeCourse(models.Model): title = models.CharField(max_length=32) class PricePolicy(models.Model): period = models.IntegerField() price = models.PositiveIntegerField() content_type = models.ForeignKey(to=ContentType,null=True) # GenericForeignKey不会在数据库生成字段,只用于查询和插入 object_id = GenericForeignKey('content_type','object_id')
3.通过课程id,获取课程信息和价格策略
urls.py
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^test/',views.addPrice) ]
views.py
from django.shortcuts import * from app01.models import * # Create your views here. def addPrice(request): # 通过课程id,获取课程信息和价格策略 course = Course.objects.filter(pk=1).first() print(course.policy.all()) for i in course.policy.all(): print(i.price) # 查专题 degree = DegreeCourse.objects.filter(pk=1).first() for i in degree.policy.all(): print(i.price) return HttpResponse('ok')
models.py
from django.db import models # Create your models here. from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation class Course(models.Model): title = models.CharField(max_length=32) # 不会再数据库生成字段,只用来查询 policy = GenericRelation('PricePolicy',object_id_field='object_id',content_type_field='contentType') class DegreeCourse(models.Model): title = models.CharField(max_length=32) class PricePolicy(models.Model): period = models.IntegerField() price = models.PositiveIntegerField() content_type = models.ForeignKey(to=ContentType,null=True) # GenericForeignKey不会在数据库生成字段,只用于查询和插入 object_id = GenericForeignKey('content_type','object_id')