赞
踩
转自:https://blog.csdn.net/a_9884108/article/details/18815965
Django中Model的继承有三种:
1、抽象继承
2、多表继承
3、proxy model(代理model)
第一种抽象继承,创建一个通用父类,为了使父类不会被创建,在抽象父类的Meta中设置abstract=True就可以。子类会继承父类相同的字段.
子类模型Student就会有s_name, s_age, s_sex三个字段
- class CommonInfo(models.Model):
- s_name = models.CharField(max_length=32)
- s_age = models.PositiveIntegerField(default=22)
-
- class Meta:
- abstract = True
-
- class Student(CommonInfo):
- home_group = models.CharField(max_length=32)
对于内联的Meta类的继承,一般的,父类的Meta类的属性会继承给子类,子类也可以在自己的Meta中重写或者拓展父类的Meta,拓展的话主要是继承父类的Meta:
-
- class CommonInfo(models.Model):
- ...
- class Meta:
- abstract = True
- ordering = ['name']
-
- class Student(CommonInfo):
- ...
- class Meta(CommonInfo.Meta):
- db_table = 'student_info'
继承时,Django 会对基类的 Meta 内嵌类做一个调整:在安装 Meta 属性之前,Django 会设置 abstract=False。 这意味着抽象基类的子类不会自动变成抽象类。当然,你可以让一个抽象类继承另一个抽象基类,不过每次都要显式地设置 abstract=True 。
对于抽象基类而言,有些属性放在 Meta 内嵌类里面是没有意义的。例如,包含 db_table 将意味着所有的子类(是指那些没有指定自己的 Meta 内嵌类的子类)都使用同一张数据库表,一般来说,这并不是我们想要的。
第二种多表继承,其中父类也是一个Django模型,并且会创建一个数据表,多表继承是Django中隐式的一对一关系:
- class Place(models.Model):
- name = models.CharField(max_length=50)
- address = models.CharField(max_length=80)
-
- class Restaurant(Place):
- serves_hot_dogs = models.BooleanField()
- serves_pizza = models.BooleanField()
这里,MyPerson没有多创建数据表,MyPerson也是对Person的数据表进行操作,一般的,我们可以把MyPerson当做Person来使用,只是在do_something这个方法略有不同,比如
- >>> p = Person.objects.create(first_name="foobar")
- >>> MyPerson.objects.get(first_name="foobar")
- <MyPerson: foobar>
代理模型和原模型的区别如下面:
- class OrderedPerson(Person):
- class Meta:
- ordering = ["last_name"]
- proxy = True
这里,OrderedPerson并不是创建了一个表,而是代理排序方法。也就是说,使用Person的检索方法并不会按last_name排序,而使用OrderedPerson检索出来的结果是按last_name排序的。OrderedPerson使用与Person类一样的检索方法。
OrderPerson返回的queryset自然是Person的,这是当然的。我们不能要求django返回OrderedPerson类的queryset,因为OrderedPerson只是代理而已,又不是真实的数据库表类。
注意的是,proxy model不能继承于抽象类,这是因为代理model是操作连接数据库的,也不能多重继承~因为你多重继承了,代理model就不知道去哪个父类找属性了
如果不指定代理model的manage,则代理model会自动继承父类的manage。我们也可以手动设置代理model的manage,这样,代理模型和父类模型的manage就分开了
为代理模型添加manage有两种方法:
一是直接在代理模型中直接指定manage
- class NewManager(models.Manager):
- ...
-
- class MyPerson(Person):
- objects = NewManager()
-
- class Meta:
- proxy = True
另外一种是当你不想覆盖父类模型中的manage但又想添加额外的manage,我们可以新建一个抽象模型,然后定义其manage,之后继承该抽象模型,如:
- # Create an abstract class for the new manager.
- class ExtraManagers(models.Model):
- secondary = NewManager()
-
- class Meta:
- abstract = True
-
- class MyPerson(Person, ExtraManagers):
- class Meta:
- proxy = True
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。