Django之Contenttype

Contenttype的运用场景

      当我们在设计如下数据库的表关联中,通过此方法来关联不同的数据库表,可以避免后期在增加不同的表后,修改策略表的表结构。

  

 

     但是,不完美。如果我们修改了一个表的表名,则需要修改策略表中所有关联表的名称。

      改进方法,再新建一张表存存储所有的表名,这样就只需要修改一个地方即可。如下

      

 

Contenttype的运用方法      

      在Django中,的Contenttype组件,可以完成此功能,不需要我们单独在写此功能。

      运用组件,需要导入所用文件。

         # GenericRelation用于反向查找。GenericForeignKey用于关联所有数据库表中的值,快速实现contenttype操作。        

          from django.contrib.contenttypes.fields import GenericForeignKey,GenericRelation

          from django.contrib.contenttypes.models import ContentType

 1 from django.db import models
 2 from django.contrib.contenttypes.fields import GenericForeignKey,GenericRelation
 3 from django.contrib.contenttypes.models import ContentType
 4 
 5 
 6 class DegreeCourse(models.Model):
 7     """
 8     学位课
 9     """
10     title = models.CharField(max_length=32)
11     # 不生成字段,仅用于反向查找
12     price_policy_list = GenericRelation("PriceStrategy")
13 
14 
15 class Course(models.Model):
16     """
17     普通课程
18     """
19     title = models.CharField(max_length=32)
20     # 不生成字段,仅用于反向查找
21     price_policy_list = GenericRelation("PriceStrategy")
22 
23 
24 class VIPCourse(models.Model):
25     """
26     VIP课程
27     """
28     title = models.CharField(max_length=32)
29     # 不生成字段,仅用于反向查找
30     price_policy_list = GenericRelation("PriceStrategy")
31 
32 
33 class PriceStrategy(models.Model):
34     """价格策略"""
35     price = models.IntegerField()
36     cycle = models.IntegerField()
37 
38     content_type = models.ForeignKey(ContentType,verbose_name="关联的表名称",on_delete=models.DO_NOTHING)
39     object_id = models.IntegerField(verbose_name="关联的课程ID")
40     # 帮助快速实现contenttype操作
41     content_object = GenericForeignKey('content_type', 'object_id')

 

      在视图中

 1 def Test(request):
 2     # 从不同的课程表中获取到我们需要做价格策略的课程
 3     obj = models.Course.objects.filter(title="rest_framework").first()
 4     # 将我们需要做的策略create到策略表中。
 5     # content_object,帮我自动去content_type中获取到关联的数据库表名的ID,添加到策略表中
 6     models.PriceStrategy.objects.create(price=9.9, cycle=30, content_object=obj)
 7 
 8     # 反向查询获取,Course表中Id为1的课程的所有价格策略
 9     c = models.Course.objects.filter(id=1).first()
10     price_list = c.price_policy_list.all()
11 
12     print(price_list)
13 
14     return HttpResponse("ok")

 

posted @ 2019-05-22 23:38  cunzhishu  阅读(99)  评论(0)    收藏  举报