ContentType是Django內置的一個應用,能夠追蹤項目中全部app和model的對應關係,並記錄在ContentType表中。數據庫
數據庫遷移後會自動生成django_content_type表,有新的表生成,數據庫遷移時,會自動增長表記錄django
一張表與多張表有一對多的關係時app
以商品與很優惠券的表關係爲例spa
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)
缺點: 每增長一張表,關係表的結構就要多加一個字段。code
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
正常查詢對象
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提供的簡便查詢blog
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()