Django之ContentType组件

一、需求

  给商品创建优惠券;

  看看下面表结构:

class Food(models.Model):
    """
    id   name
    1     面条
    """
    name = models.CharField(max_length=32)

    def __str__(self):
        return self.name

class Fruit(models.Model):
    """
    id     name
    1      苹果
    """
    name = models.CharField(max_length=32)
    coupons = GenericRelation(to="Coupon")  # 定义反向查询字段

    def __str__(self):
        return self.name

class Coupon(models.Model):
    """
    优惠券表
    id  name    appliance_id    food_id     fruit_id
    1   通用优惠券   null            null        null
    2   冰箱折扣券   1               null        null
    3   电视折扣券   2               null        null
    4   苹果满减卷   null            null        1
    我每增加一张表就要多增加一个字段
    """
    name = models.CharField(max_length=32)
    # 这样写,每增加一张表就要多增加一个字段, 所以我们可以创建第四张表
    appliance = models.ForeignKey(to="Appliance")
    food = models.ForeignKey(to="Food")
    fruit = models.ForeignKey(to="Fruit")

  创建第四张表,改善上面的写法:遇到这种一张表要跟多张表进行外键关联

class Appliance(models.Model):
    name = models.CharField(max_length=32)

class Food(models.Model):
    """
    id   name
    1     面条
    """
    name = models.CharField(max_length=32)

    def __str__(self):
        return self.name

class Fruit(models.Model):
    """
    id     name
    1      苹果
    """
    name = models.CharField(max_length=32)
    coupons = GenericRelation(to="Coupon")  # 定义反向查询字段

    def __str__(self):
        return self.name

class Coupon(models.Model):
    """
    优惠券表
    id       name           content_type_id     object_id
    1     面条优惠券             1                 1
    1     苹果优惠券             2                1
    """
    name = models.CharField(max_length=32)
    # 这样写,每增加一张表就要多增加一个字段, 所以我们可以创建第四张表ContentType
    content_type_id =
    object_id = 

class ContentType(models.Model):
    # django自带这张表,已经帮我们做好了,就是django的ContentType组件,我们直接拿过来用就行
    """
    id    app_name    model_class
    1      app01         Food
    2      app01         Fruit
    3      app01         Appliance
    """
    pass

  其实django已经帮我写好了这张ContentType表,我们只需要导入使用即可;

二、使用django自带的ContentType表

  ContentType是Django的内置的一个应用,可以追踪项目中所有的APP和model的对应关系,并记录在ContentType表中。

  当我们的项目做数据迁移后,会有很多django自带的表,其中就有django_content_type表;

ContentType组件应用:

  -- 在model中定义ForeignKey字段,并关联到ContentType表,通常这个字段命名为content-type

  -- 在model中定义PositiveIntergerField字段, 用来存储关联表中的主键,通常我们用object_id

  -- 在model中定义GenericForeignKey字段,传入上面两个字段的名字

  --  方便反向查询可以定义GenericRelation字段

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
class Food(models.Model):
    """
    id   name
    1     面条
    """
    name = models.CharField(max_length=32)

    def __str__(self):
        return self.name

class Fruit(models.Model):
    """
    id     name
    1      苹果
    """
    name = models.CharField(max_length=32)
    coupons = GenericRelation(to="Coupon")  # 定义反向查询字段

    def __str__(self):
        return self.name

class Coupon(models.Model):
    """
    优惠券表
    id       name           content_type_id     object_id
    1     面条优惠券             1                 1
    1     苹果优惠券             2                1
    """
    name = models.CharField(max_length=32)
    # 这样写,每增加一张表就要多增加一个字段, 所以我们可以创建第四张表ContentType
    # appliance = models.ForeignKey(to="Appliance")
    # food = models.ForeignKey(to="Food")
    # fruit = models.ForeignKey(to="Fruit")

    # 第一步  先生成ForeignKey字段 关联ContentType
    content_type = models.ForeignKey(to=ContentType)
    # 第二步   生成一个IntergerField 字段关联
    object_id = models.PositiveIntegerField()
    # 第三步 生成一个GenericForeignKey 把上面两个字段注册进去
    content_obj = GenericForeignKey("content_type", "object_id")

    def __str__(self):
        return self.name

基本的操作:

class Test(APIView):

    def get(self, request):
        from django.contrib.contenttypes.models import ContentType
        # 通过contentType获取表名
        content = ContentType.objects.filter(app_label="app01", model="food").first()  # 表名都是小写
        model_class = content.model_class()  # 通过上一步获取的contentType对象获取 里面的表对象
        ret = model_class.objects.all()  # 查询这个表中所有的信息
        print(ret)

        # 给Food表中的面条创建一个优惠券
        noodle_obj = models.Food.objects.filter(id=2).first()  # 这里面包含了自己所在的表,和自己这条记录在那张表中的id
        models.Coupon.objects.create(name="面条优惠券", content_obj=noodle_obj)  # 只要传入上面的obj即可

        # 查询id为1的优惠券,对应那个商品信息
        coupon_obj = models.Coupon.objects.filter(id=1).first()
        goods_obj = coupon_obj.content_obj  # 拿到对应的商品对象
        print(goods_obj)
        print(goods_obj.name, goods_obj.id)

        # 查询苹果的所有优惠券
        # 因为我们定义了反向字段,所以可以这么查:
        # 首先找苹果对象
        apple_obj = models.Fruit.objects.filter(name="苹果").first()
        coupon_obj_list = apple_obj.coupons.all()  # 通过字段反向查询
        print(coupon_obj_list)
        print(coupon_obj_list.first().name)

        return Response("ok")

原作者:https://www.cnblogs.com/glh-ty/p/9703574.html

原文地址:https://www.cnblogs.com/qq631243523/p/10105178.html

时间: 2024-11-03 11:54:42

Django之ContentType组件的相关文章

【Django】ContentType组件

目录 理解 表结构 使用 @ 好,现在我们有这样一个需求,我们的商城里有很多的商品,然而节日要来了,我们要搞活动. 那么,我们就要设计优惠券,优惠券都有什么类型呢?满减的.折扣的.立减的.等等等... 我们对应着活动类型,对某类商品设计优惠卷,比如: 家电是一类商品.食物是一类商品,那么我们就可以设计家电折扣优惠券,以及食物满减优惠券等. 所以,我们一顺手,表结构就出来了: from django.db import models is_true = {'null': True, 'blank'

【Django】ContentType组件 -- 2019-08-08 18:03:22

目录 理解 表结构 使用 原文: http://106.13.73.98/__/72/ @ 好,现在我们有这样一个需求,我们的商城里有很多的商品,然而节日要来了,我们要搞活动. 那么,我们就要设计优惠券,优惠券都有什么类型呢?满减的.折扣的.立减的.等等等... 我们对应着活动类型,对某类商品设计优惠卷,比如: 家电是一类商品.食物是一类商品,那么我们就可以设计家电折扣优惠券,以及食物满减优惠券等. 所以,我们一顺手,表结构就出来了: from django.db import models i

Django 使用Contenttype组件创建多关联数据库表

from django.db import models '''contenttype使用意义:如果使用contenttypes就不需要再使用多个Foreignkey, 因为在django_content_type表已经存储了app名和model名, 所以我们只需要将我们创建的模型与django_content_type表关联起来, 然后再存储一个实例 id 即可准确定位到某个app中某个模型的具体实例 ''' '''使用Django的Contenttype字段.''' # 导入必需模块 fro

Django 之 ContentType组件

一.什么是 ContentTypes ContentTypes 是 Django 内置的一个应用,它可以追踪记录项目中所有 app 和 model 的对应关系,并记录在 django_content_type 表中. 二.ContentTypes 的应用场景 ContentTypes 适用于一张表与多张表相关关联的场景,如:一个卖课程的网站,它主要售卖两类课程(普通课程和学位课程).不同课程之间因学习周期不同,价格也不尽相同.因此就形成了每个课程可能有一个或多个价格策略.类似于下面这种: 如果我

django ContentType组件

一,需求 给商品创建优惠券: 看看下面表结构: class Food(models.Model): """ id name 1 面条 """ name = models.CharField(max_length=32) def __str__(self): return self.name class Fruit(models.Model): """ id name 1 苹果 """ n

contenttype组件、Django缓存机制以及跨域请求

1 昨日回顾 版本控制 *** (1)url=127.0.0.1/course/?version=v100000 1 versioning_class=QueryParameterVersioning 'VERSION_PARAM':'version', 'DEFAULT_VERSION':'v2', 'ALLOWED_VERSIONS':['v1','v2'] 2 配置成全局:在setting里:QueryParameterVersioning (2)重要(以后建议用这种):127.0.0.1

Django ContentType组件 需求

ContentType组件 遇到这一张表要跟多张表进行外键关联的时候~我们Django提供了ContentType组件~ ContentType是Django的内置的一个应用,可以追踪项目中所有的APP和model的对应关系,并记录在ContentType表中. 当我们的项目做数据迁移后,会有很多django自带的表,其中就有django_content_type表,我们可以去看下~~~ ContentType组件应用: -- 在model中定义ForeignKey字段,并关联到ContentT

django——contentType组件

contentType组件 django内置的一个组件,方便我们快速的进行连表操作,查询,插入数据 使用方法: 在course表中: policy = GenericRelation('PricePolicy', object_id_field='course_id', content_type_field='table_id') 在价格策略表中: content_obj = GenericForeignKey('table_id','course_id') --加的这两个字段都不会在数据库中生

Django框架(二十七)—— ContentType组件

目录 ContentType组件 一.什么是ContentType组件 二.使用ContentType 三.使用场景总结 ContentType组件 一.什么是ContentType组件 contentType是Django内置的组件,可以方便我们快速的连表查询. 可以追踪项目中所有app和model的对应关系,并记录在ContentType表中 models.py文件的表结构写好后,通过makemigrations和migrate两条命令迁移数据后,在数据库中会自动生成一个django_con