Django中Model继承的三种方式

Django中Model的继承有三种:
1、抽象继承
2、多表继承
3、proxy model(代理model)

1、抽象继承

第一种抽象继承,创建一个通用父类,为了使父类不会被创建,在抽象父类的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 内嵌类的子类)都使用同一张数据库表,一般来说,这并不是我们想要的。

2,多表继承

第二种多表继承,其中父类也是一个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就分开了

3、proxy model(代理model)

为代理模型添加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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hsw Come on

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值