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()