ContentType

1.ContentType定义

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)

缺点: 每增加一张表,关系表的结构就要多加一个字段。

通过ContentType建立的表结构

 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

4.使用

正向查询: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

反向查询:查询美的冰箱(id=1)的所有优惠券

1 #1.在电器表中找到id为1的商品
2 ele=Electrics.objects.filter(pk=1).first()
3 #2.通过coupons字段获取该商品的所有优惠券
4 ele.coupons.all()

 

 

 

 

 

 

posted @ 2018-12-05 09:18  ★行者尚★  阅读(176)  评论(0编辑  收藏  举报