Django restframework ContentType组件的基本使用

1、ContentType组件经常使用的场景,两个表之间的关系是一对多的关系,接下来可以尝试解读下面简单的例子。

一班班级信息表oneClass

ID name
1 xiaohu
2 xiaopan
3 xiaoliu
4 xiaolin

 

二班班级信息表twoClass

ID name
1 huxiao
2 panxiao
3 liuxiao
4 linxiao

所有班级的成绩表allGrade

ID course grade oneClass_id twoClass_id
 1  chinese  99  1  
 2  math  100  1  
 3  english  110  2  
 4  chinese  98    2
 5  math  120    2
6 english 100   3

 常用的方式就是在allGrade表新增一列和班级表相关的字段(一般是主键),但是这样就会存在一个弊端:如果新增了几个班级,那么allGrade表格就相对应的新增列,所以需要对allGrade表格进行优化,优化如下

 ID  course  grade  table_name record_id 
 1  chinese  99  oneClass  1
 2  math  100  oneClass  1
 3  english  110  oneClass  2
 4  chinese  98  twoClass  2
 5  math  120  twoClass  2
 6  english  100  twoClass  3

这样优化的话,allGrade表就不再新增列了,通过这两列就可以关联所有的班级表了,但是会发现另一个弊端,就是班级表的名称改变了,allGrade的表格名称就要改变,消耗的资源就多了,那么就可以需要一个中间表来优化这个allGrade表,这个中间表,Django restframework框架已经为我们提供了。这个表格的名称就是ContentType,而且我们在建立模型的过程中,框架会自动帮我们把建立好的模型表添加到下面的表格中。

ID app_label model
1 myApp oneClass
2 myApp twoClass

 

ID  course grade table_id record_id
1 chinese 99 1 1
2 math 100 1 1
3 english 110 1 2
4 chinese 98 2 2
5 math 120 2 2
6 english 110 2 3

在建立模型(创建表格)的时候,向从一访问多的数据时,需要在一的模型中添加一个属性,该属性不会被创建为表格字段。


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

class
OneClass(models.Model): name = models.CharField(max_length=50) oneClass_list = GenericRelation("AllGrade") class TwoClass(models.Model): name = models.CharField(max_length=50) twoClass_list = GenericRelation("AllGrade") class AllGrade(models.Model): course = models.CharField(max_length=50) grade = models.DecimalField() table_id = models.ForeignKey(ContentType, on_delete=models.CASCADE) record_id = models.IntegerField() content_obj = GenericForeignKey("table_id", "record_id")

 AllGrade表格中的content_obj的语句主要是方便表新增记录。示例:新增一条记录的常用句式如下

class_obj = OneClass.object.filter(name="xiaohu").first()
model_obj = ContentType.object.filter(name="oneclass").first()
# 新增一条记录
AllGrade.object.create(course="化学", grade=60, table_id=model_obj.id, record_id=class_obj.id)

如果使用content_obj的语句就不一样了,语句如下

class_obj = OneClass.object.filter(name="xiaohu").first()
# 新增一条记录
AllGrade.object.create(course="化学", grade=60, content_obj=class_obj)

OneClass和TwoClass表都有一行GenericRelation("AllGrade")代码,这一行常用的示例:根据学生的id获取所有的成绩

# 获取xiaohu的所有成绩
student = OneClass.object.filter(name="xiaohu").first()
grade_list = student.oneClass_list.all()
# 获取linxiao的所有成绩
student = TwoClass.object.filter(name="linxiao").first()
grade_list = student.twoClass_list.all()

 

posted @ 2020-06-18 19:37  xsha_h  阅读(304)  评论(0编辑  收藏  举报