zoukankan      html  css  js  c++  java
  • Django的ContentType组件

    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)

  • 相关阅读:
    Linux下运行jmeter
    jmeter压力测试
    CSS流体(自适应)布局下宽度分离原则——张鑫旭
    立即调用的函数表达式
    完善:HTML5表单新特征简介与举例——张鑫旭
    div模拟textarea文本域轻松实现高度自适应——张鑫旭
    备忘:CSS术语词汇表——张鑫旭
    拜拜了,浮动布局-基于display:inline-block的列表布局——张鑫旭
    使用CSS3改变文本选中的默认颜色——张鑫旭
    :after伪类+content内容生成经典应用举例——张鑫旭
  • 原文地址:https://www.cnblogs.com/staff/p/12668915.html
Copyright © 2011-2022 走看看