1、contenttype:在django中将models.py文件的表结构写好后,通过makemigrations和migrate两条命令进行数据库迁移后,在数据库中会自动生成一个django_content_type表。
2、contenttype表的字段:
id:id;
app_label:新的model所对应的app应用名称;
model:model的名称 即app应用中的model.py所对应的新增的表结构(类名)。
3、contenttype表的作用:每当我们创建了一个新的model并执行数据库迁移后,ContentType表中就会自动新增一条记录。比如我在应用api的models.py中创建表class Course(models.Model): pass。从数据库查看ContentType表会相应的增加一条数据 id:--, app_label:api, model:course。
4、应用场景:当出现一张表的数据要与多张表的数据关联的时候使用,
示例:现有两种课程(按不同标准收费的课程),每种课程对应多种收费方式,首先想到的是创建一张课程表,然后创建一张收费标准表让他们相关联,这种方法可行但存在缺陷;
表单创建:
from django.db import models
# 课程种类 轻课和学位课
class Course(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
course_type = models.CharField(max_length=32, default='轻课')
class PricePolicy(models.Model):
id = models.AutoField(primary_key=True)
# 轻课的授课周期 不同周期收费不同
period = models.CharField(max_length=32, null=True)
# 学位课的授课方式 面授和网课收费不同
degree_type = models.CharField(max_length=32, null=True)
price = models.DecimalField(max_digits=8, decimal_places=2)
course = models.ForeignKey(to=Course)
数据插入:
import os
if __name__ == '__main__':
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "luffy_bac.settings")
application = get_wsgi_application()
from api import models
c1 = models.Course.objects.create(name='django', course_type='轻课')
c2 = models.Course.objects.create(name='linux', course_type='轻课')
c3 = models.Course.objects.create(name='python', course_type='学位课')
c4 = models.Course.objects.create(name='go', course_type='学位课')
models.PricePolicy.objects.create(period='10', price=19.9, course=c1)
models.PricePolicy.objects.create(period='20', price=29.9, course=c1)
models.PricePolicy.objects.create(period='30', price=49.9, course=c1)
models.PricePolicy.objects.create(period='10', price=19.9, course=c2)
models.PricePolicy.objects.create(period='20', price=69.9, course=c2)
models.PricePolicy.objects.create(period='30', price=79.9, course=c2)
models.PricePolicy.objects.create(degree_type='面授', price=28888.8, course=c3)
models.PricePolicy.objects.create(degree_type='网课', price=18888.8, course=c3)
models.PricePolicy.objects.create(degree_type='面授', price=20000.2, course=c4)
models.PricePolicy.objects.create(degree_type='网课', price=10000.2, course=c4)
api_course
api_pricepolicy
查询:
# 查询django课程信息的所有价格策略
course = models.Course.objects.get(pk=1)
# policy_list 就是django这门课所有的价格策略对象
policy_list = course.pricepolicy_set.all()
for policy in policy_list:
print(policy.price)
不难发现此种建标方案当出现需要添加新的课程类配合新的收费标准时,需要在pricepolicy中增加新的字段,需要修改表结构。
---》使用contenttype可以避免:
eg:表单的创建
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
class Course(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=32)
#其他字段
# 不会在数据库中生成字段,只用于数据库操作
policy = GenericRelation(to='PricePolicy')
class DegreeCourse(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=32)
# 它自己的字段
policy = GenericRelation(to='PricePolicy')
class LiteCourse(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=32)
# 它自己的字段
policy = GenericRelation(to='PricePolicy')
class PricePolicy(models.Model):
id=models.AutoField(primary_key=True)
period=models.IntegerField()
price=models.DecimalField(max_digits=8,decimal_places=2)
object_id=models.IntegerField()
# table_id=models.IntegerField()
#不要加引号
content_type=models.ForeignKey(to=ContentType,null=True)
# 引入一个字段,不会在数据库中创建,只用来做数据库操作
# content_obj = GenericForeignKey('content_type','object_id')
content_obj = GenericForeignKey()
# 为django免费课,添加三个价格策略
查询操作:
import os
if __name__ == '__main__':
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "luffy_city.settings")
import django
django.setup()
from api import models
from django.contrib.contenttypes import models as co_model
# contenttype提供的快速插入的方法
#
# course = models.Course.objects.get(pk=1)
# ret=models.PricePolicy.objects.create(period=30, price=199.9,content_obj=course)
#为学位课,添加一个价格策略
# degree_course=models.DegreeCourse.objects.get(pk=1)
# ret = models.PricePolicy.objects.create(period=180, price=28888, content_obj=degree_course)
# 查询所有价格策略,并且显示对应的课程名称
# price_policy_list=models.PricePolicy.objects.all()
# for price_policy in price_policy_list:
# print(type(price_policy.content_obj))
# print(price_policy.content_obj.name)
# 查询django课程信息的所有价格策略
# course=models.Course.objects.get(pk=1)
# #policy_list 就是django这门课所有的价格策略对象
# policy_list=course.policy.all()
# for policy in policy_list:
# print(policy.price)
# 查询python全栈开发的所有价格策略
# degree_course=models.DegreeCourse.objects.get(pk=1)
# policy_list=degree_course.policy.all()
# for policy in policy_list:
# print(policy.price)
来源:oschina
链接:https://my.oschina.net/u/4397893/blog/4089327