Django :Content-Type组件
Content_Type 组件
用法:
model.py:
from django.db import models # Create your models here. class Food(models.Model): title = models.CharField(max_length=32) class Foute(models.Model): title = models.CharField(max_length=32)
现在有食物和水果两张表,要为其创建一个优惠卷,应该怎么创建呢?
按照之前的创建表关系,首先创建一个优惠卷表,然后在创建一个关联表:
class Coupon1(models.Model): ''' 优惠券信息表:优惠劵 --> 商品id ''' title = models.CharField(max_length=32) object_id = models.ForeignKey(to="Table",to_field="object_id") class Table(models.Model): ''' 表关系:商品id --> 所在表 ''' object_id = models.IntegerField() table_id = models.IntegerField()
在食物和水果两张表分表建立多对多关系,将商品表和表关系Table建立关联:
table = models.ManyToManyField(to="Table", )
这样看起来是不是有些复杂呢,对于这种关联关系Content_Type就可以给我们解决,不需要创建多余表
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.fields import GenericForeignKey,GenericRelation class Food(models.Model): title = models.CharField(max_length=32) # 只实现relation关系 是隐形关系 不生成实际字段 只用于反向查询 coupons = GenericRelation(to="Coupon") class Fruit(models.Model): title = models.CharField(max_length=32) # 只实现relation关系 是隐形关系 不生成实际字段 只用于反向查询 coupons = GenericRelation(to="Coupon" class Coupon(models.Model): title = models.CharField(max_length=32) content_type = models.ForeignKey(to=ContentType, on_delete=models.CASCADE) object_id = models.IntegerField() # 只实现relation关系 是隐形关系 不生成实际字段 只用于反向查询 content_obj = GenericForeignKey("content_type","object_id") def __str__(self): return self.title
这样看起来是不是就简单多了呢,现在进行数据库迁移,你会看到下面几个表:
django_content_type表是存储我们所有的关系表,app_label表示app名字,model对应具体表。我们创建的三个表也会在里面自动 生成
Content_Type的数据操作
1、增:
# =============== 增加数据 # 方式一:传统方法创建 coupon_obj1 = Coupon.objects.create(title="面包九五折", object_id=1,content_type_id=7) coupon_obj2 = Coupon.objects.create(title="苹果九折", object_id=1,content_type_id=8) coupon_obj1 = coupon_obj1.content_type coupon_obj2 = coupon_obj2.content_type print(coupon_obj1.app_labeled_name) # 方式二: # 通过GenericForeignKey创建,GenericForeignKey会自动绑定到对应的content_type Coupon.objects.create(title="双十一大减价全场一折",content_obj=food_obj)
2、查 # ================ 查询数据
# ========= 1、查询面包有多少优惠卷 coupons = food_obj.conupus.all() print(coupons) # <QuerySet [<Coupon: 面包九五折>, <Coupon: 双十一大减价全场一折>, <Coupon: 面包九五折>,] # ========= 2、通过优惠券查询面包
coupons_obj = Coupon.objects.filter(object_id=1).first() content_obj = coupons_obj.content_obj print(content_obj.title) # 面包 # ======== 3、基于Content_Type找表模型 以便获取表的其他数据 # 此时content_obj就是ContentType的一个对象 content_obj = ContentType.objects.filter(app_label="demo",model="food").first() # 调用ContentType对象的model_class属性获取表模型 model_class = content_obj.model_class() print(model_class.objects.all()) # <QuerySet [<Food: Food object (1)>, <Food: Food object (2)>]>
适用情景:
Content_Type组件适用于商城类项目,用于创建多个外键关系的表关系