ContentType是Django内置的一个应用,可以追踪项目中所有app和model的对应关系,并记录在ContentType表中。
2.特点
数据库迁移后会自动生成django_content_type表,有新的表生成,数据库迁移时,会自动增加表记录
3.应用场景
一张表与多张表有一对多的关系时
以商品与很优惠券的表关系为例
正常表结构建立
1 from django.db import models 2 3 class Electrics(models.Model): 4 """ 5 id name 6 1 日立冰箱 7 2 三星电视 8 3 小天鹅洗衣机 9 """ 10 name = models.CharField(max_length=32) 11 12 13 class Foods(models.Model): 14 """ 15 id name 16 1 面包 17 2 烤鸭 18 """ 19 name = models.CharField(max_length=32) 20 21 22 class Clothes(models.Model): 23 name = models.CharField(max_length=32) 24 25 26 class Coupon(models.Model): # 特殊关系表 27 28 # id name electric_id food_id cloth_id more... 29 # 1 通用优惠券 null null null 30 # 2 冰箱满减券 2 null null 31 # 3 面包狂欢节 null 1 null 32 33 name = models.CharField(max_length=32) 34 electric = models.ForeignKey(to='Electrics', null=True,on_delete=models.CASCADE) 35 food = models.ForeignKey(to='Foods', null=True,on_delete=models.CASCADE) 36 cloth = models.ForeignKey(to='Clothes', null=True,on_delete=models.CASCADE)
缺点: 每增加一张表,关系表的结构就要多加一个字段。
1 from django.db import models 2 from django.contrib.contenttypes.models import ContentType 3 from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation 4 5 6 class Electrics(models.Model): 7 name = models.CharField(max_length=32) 8 price = models.IntegerField(default=100) 9 coupons = GenericRelation(to='Coupon') # 用于反向查询,不会生成表字段 10 11 def __str__(self): 12 return self.name 13 14 15 class Foods(models.Model): 16 name = models.CharField(max_length=32) 17 price=models.IntegerField(default=100) 18 coupons = GenericRelation(to='Coupon') 19 20 def __str__(self): 21 return self.name 22 23 24 class Clothes(models.Model): 25 name = models.CharField(max_length=32) 26 price = models.IntegerField(default=100) 27 coupons = GenericRelation(to='Coupon') 28 29 def __str__(self): 30 return self.name 31 32 33 class bed(models.Model): 34 name = models.CharField(max_length=32) 35 price = models.IntegerField(default=100) 36 coupons = GenericRelation(to='Coupon') 37 38 39 class Coupon(models.Model): 40 """ 41 Coupon 42 id name content_type_id object_id_id 43 美的满减优惠券 9(电器表electrics) 3 44 猪蹄买一送一优惠券 10 2 45 南极被子买200减50优惠券 11 1 46 """ 47 name = models.CharField(max_length=32) 48 49 content_type = models.ForeignKey(to=ContentType) # step 1 外键关联contenttype表 50 object_id = models.PositiveIntegerField() # step 2 标记指定的指定id的对象 51 content_object = GenericForeignKey('content_type', 'object_id') # step 3 用于反向查询的字段 52 53 def __str__(self): 54 return self.name
正向查询:id为1的优惠券对应的商品名称
正常查询
1 #0.引入需要用到的表 2 from app01.models import * 3 from django.contrib.contenttypes.models import ContentType 4 #1.找到主键为1的优惠券对象 5 coupon=Coupon.objects.filter(pk=1).first() 6 #2.找到该优惠券对相应的contentType中的相应对象的id 7 contentType_obj_id=coupon.content_type_id 8 #3.找到该优惠券对相应的contentType中的相应对象 9 contentType_obj=ContentType.objects.filter(pk=contentType_obj_id).first() 10 #4.找到该对象对应的模型表 11 model_class=contentType_obj.model_class() 12 #5.在模型表中查找优惠券对应的商品名称 13 ge_name=model_class.objects.filter(id=coupon.object_id)
contentType提供的简便查询
1 #0.引入需要用到的表 2 from app01.models import * 3 from django.contrib.contenttypes.models import ContentType 4 #1.找到主键为1的优惠券对象 5 coupon=Coupon.objects.filter(pk=1).first() 6 #2***.用优惠券对象直接.content_obj,Django会替我们找到该优惠券对应的商品对象*** 7 coupon.content_object
1 #1.在电器表中找到id为1的商品 2 ele=Electrics.objects.filter(pk=1).first() 3 #2.通过coupons字段获取该商品的所有优惠券 4 ele.coupons.all()