Django-contenttype组件

Contenttype组件一般使用在表结构是一种策略模式中,能够帮助我们快速的操作。

表关系

如下设计:有一张价格表,有三种不同课程类型(大课、小课、软件服务),而且每种课程(大课中的Python)因为周期(30 60 90 )的不同而价格也不同。

在django_content_type表中有我们所有的makemigrations操作的表名记录。

Models

from django.db import models 
from django.contrib.contenttypes.models import ContentType 
from django.contrib.contenttypes.fields import GenericForeignKey,GenericRelation

# Create your models here.

class BigCourse(models.Model):
	"""大课"""
	name = models.CharField(max_length=128)
    
    # 不会创建额外的列,帮助快速操作
    price_policy = GenericRelation("PricePolicy")
    
class SmallCourse(models.Model):
	"""小课"""
	name = models.CharField(max_length=128)
	
class PricePolicy(models.Model):
    """价格策略"""
	period = models.IntegerField(verbose_name="周期")    
	price = models.FloatField(verbose_name="价格")
    
    # 跟django_content_type表做ForeignKey
    content_type = models.ForeignKey(ContentType)    
    object_id = models.PositiveIntegerField()
    
    # 不会创建额外的列,帮助快速操作,不用分开给content_type,object_id传值
    content_object = GenericForeignKey('content_type', 'object_id')

添加数据

创建一个大课 & 三个价格策略

# 以前的方法:

big_object = models.BigCourse.objects.create(name='Python')
ct = ContentType.objects.filter(app_label='app02',model='bigcourse').first() 
models.PricePolicy.objects.create(
	period=30,
	price=10000,
	content_type=ct,
	object_id=big_object.id 
	)
models.PricePolicy.objects.create(
	period=60,
    price=15000,
    content_type=ct,
    object_id=big_object.id
    ) 
models.PricePolicy.objects.create(
	period=90,    
	price=18000,    
	content_type=ct,    
	object_id=big_object.id
	)

使用ContentType的方法:

添加一个字段GenericForeignKey(),不会产生额外的列,能够帮助我们快速操作,

不用分开给content_type,object_id传值。

# 简单的方法
big_object = models.BigCourse.objects.create(name='Python')

models.PricePolicy.objects.create(
	period=30,
    price=10000,
    content_object=big_object 
) 
models.PricePolicy.objects.create(
	period=60,
    price=15000,
    content_object=big_object 
)
models.PricePolicy.objects.create(
	period=90,
    price=18000,
    content_object=big_object 
)

创建一个小课 & 三个价格策略

small_object = models.SmallCourse.objects.create(name='Django')

models.PricePolicy.objects.create(
    period=7,
    price=1000,
    content_object=small_object
)

models.PricePolicy.objects.create(
    period=15,
    price=1500,
    content_object=small_object
)

models.PricePolicy.objects.create(
    period=30,
    price=2000,
    content_object=small_object
)

总结:GenericForeignKey能快速对ContentType字段与另一个object字段进行快速操作

获取所有的价格策略

data_list = models.PricePolicy.objects.all() 
for item in data_list:    
    item.id    
    item.price
    
    # 能够字段找到与之关联的对象:BigCourse/SmallCourse 
    item.content_object

获取大课Python的所有价格策略

在BigCourse中添加price_policy = GenericRelation("PricePolicy")字段,可以很快的进行操作

course_object = models.BigCourse.objects.filter(name='Python').first()
price_object_list = course_object.price_policy.all()
posted @ 2020-08-27 14:02  SensorError  阅读(117)  评论(0编辑  收藏  举报