要一直走下去

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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)

 

posted on 2020-04-09 18:59  要一直走下去  阅读(139)  评论(0编辑  收藏  举报