ContentType使用场景:
一张表要跟多张表建立外键关系的时候,都可以考虑使用Django的ContentType组件
-----------------------------------------例子----------------------------------------
需求:
商城项目,
商城有很多商品:家电,食物,水果等
搞优惠活动:有优惠券,满减的,折扣的等
先设计表结构:
1.食物表:Food(id,name)
2.水果表:Fruit(id,name)
3.优惠券表:Coupon(id, title, food_id,fruit_id)
水果优惠卷,food_id=null
食物优惠券,fruit_id=null
...
如果有40种商品,就有40个外键关系,这就不合理了
所以优惠卷表不能这样设计
优化后的表设计:
1.食物表:Food(id,name)
2.水果表:Fruit(id,name)
3.优惠券表:Coupon(id, title, table_id,object_id)
说明:table_id是Table表的外键,object_id是table_id对应的表的外键
4.存所有表的表:Table(id,app_name,table_name)
优化之后,如果有40种商品,只需要给Table表添加记录就行。
Table表就是Django的ContentType组件自动创建的
表名是:django_content_type
注意:GenericRelation 是 GenericForeignKey的反向查询字段
创建表结构:
from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation class Food(models.Model): name = models.CharField(max_length=32, verbose_name="食品名称") # 不会生成字段 只用于反向查询 coupons = GenericRelation(to="Coupon") class Fruit(models.Model): name = models.CharField(max_length=32, verbose_name="水果名称") class Coupon(models.Model): name = models.CharField(max_length=32, verbose_name="折扣名称") content_type = models.ForeignKey(to=ContentType, on_delete=None) object_id = models.IntegerField() content_object = GenericForeignKey("content_type", "object_id") # 不会生成字段,只用于添加记录
# 增加面包优惠券
food_obj = Food.objects.filter(id=1).first()
Coupon.objects.create(title="面包九五折", content_object=food_obj)
# 查询面包有哪些优惠券:
coupons = food_obj.coupons.all()
# 优惠券查对象
coupon_obj = Coupon.objects.filter(id=1).first()
content_object = coupon_obj.content_object
# 通过ContentType找表模型[model_class]
content = ContentType.objects.filter(app_label="demo", model="food").first()
model_class = content.model_class()
ret = model_class.objects.all()
print(ret)