当前位置:   article > 正文

Django中Model继承的三种方式_django model 继承

django model 继承

转自: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三个字段

  1. class CommonInfo(models.Model):
  2. s_name = models.CharField(max_length=32)
  3. s_age = models.PositiveIntegerField(default=22)
  4. class Meta:
  5. abstract = True
  6. class Student(CommonInfo):
  7. home_group = models.CharField(max_length=32)

对于内联的Meta类的继承,一般的,父类的Meta类的属性会继承给子类,子类也可以在自己的Meta中重写或者拓展父类的Meta,拓展的话主要是继承父类的Meta:

  1. class CommonInfo(models.Model):
  2. ...
  3. class Meta:
  4. abstract = True
  5. ordering = ['name']
  6. class Student(CommonInfo):
  7. ...
  8. class Meta(CommonInfo.Meta):
  9. db_table = 'student_info'

继承时,Django 会对基类的 Meta 内嵌类做一个调整:在安装 Meta 属性之前,Django 会设置 abstract=False。 这意味着抽象基类的子类不会自动变成抽象类。当然,你可以让一个抽象类继承另一个抽象基类,不过每次都要显式地设置 abstract=True 。

对于抽象基类而言,有些属性放在 Meta 内嵌类里面是没有意义的。例如,包含 db_table 将意味着所有的子类(是指那些没有指定自己的 Meta 内嵌类的子类)都使用同一张数据库表,一般来说,这并不是我们想要的。

第二种多表继承,其中父类也是一个Django模型,并且会创建一个数据表,多表继承是Django中隐式的一对一关系:

  1. class Place(models.Model):
  2. name = models.CharField(max_length=50)
  3. address = models.CharField(max_length=80)
  4. class Restaurant(Place):
  5. serves_hot_dogs = models.BooleanField()
  6. serves_pizza = models.BooleanField()

 

这里,MyPerson没有多创建数据表,MyPerson也是对Person的数据表进行操作,一般的,我们可以把MyPerson当做Person来使用,只是在do_something这个方法略有不同,比如

  1. >>> p = Person.objects.create(first_name="foobar")
  2. >>> MyPerson.objects.get(first_name="foobar")
  3. <MyPerson: foobar>

代理模型和原模型的区别如下面:

  1. class OrderedPerson(Person):
  2. class Meta:
  3. ordering = ["last_name"]
  4. 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

  1. class NewManager(models.Manager):
  2. ...
  3. class MyPerson(Person):
  4. objects = NewManager()
  5. class Meta:
  6. proxy = True

另外一种是当你不想覆盖父类模型中的manage但又想添加额外的manage,我们可以新建一个抽象模型,然后定义其manage,之后继承该抽象模型,如:

  1. # Create an abstract class for the new manager.
  2. class ExtraManagers(models.Model):
  3. secondary = NewManager()
  4. class Meta:
  5. abstract = True
  6. class MyPerson(Person, ExtraManagers):
  7. class Meta:
  8. proxy = True

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/769264
推荐阅读
相关标签
  

闽ICP备14008679号