10、Django_模型类的继承以及用包来管理模型类

2019-10-12  本文已影响0人  猪儿打滚

面向对象语言的三大特性:多态、封装、继承。Django中模型类也拥有这些特性,本章说明下模型类的继承

概述

Django中,不管是直接继承也好,间接继承也罢,所有的模型类的基类是django.db.models.Model

一、继承抽象基类
class Animal(models.Model):
    named = models.CharField(max_length=64)
    age = models.PositiveIntegerField()

    class Meta:
        abstract = True
        ordering = ['age']


class Cat(Animal):
    skill = models.CharField(max_length=32)
    
    class Meta:
        db_table = 'cat'
class Animal(models.Model):
    key = models.ManyToManyField(
        xxxModel,
        related_name='%(app_label)s_%(class)s_related',
        related_query_name='%(app_label)s_%(class)s'
    )

    class Meta:
        abstract = True
        ordering = ['age']
### 同个应用的模块类
class Cat(Animal):
    skill = models.CharField(max_length=32)

class Dog(Animal):
    skill = models.CharField(max_length=32)

### 其它应用的模块类(otherApp)
from modelsinherit.models import Animal

class Bird(Animal):
     skill = models.CharField(max_length=32)
二、多表继承/继承正常模型类

这种继承方式,父类和子类都是子父类都是独立自主,在数据库中创建数据表,功能完整的模型类。并且内部隐含了一对一的关系

class Animal(models.Model):
    named = models.CharField(max_length=64)
    age = models.PositiveIntegerField()

class Cat(Animal):
    skill = models.CharField(max_length=32)
class Cat(Animal):
    ordering = []
class Cat(Animal):
    skill = models.ManyToManyField(
       Animal,
       related_name = 'related_skill'  # 指定related_name
)
三、代理模型

有时候,我们只想更改模型类在python层面的行为,比如说:添加一个新的方法,更改默认的manager管理器。着时候就可以使用代理模型
使用代理模型时,可以创建、更新、删除代理模型的实例,并且所有的数据都可以和使用原始模型(非代理模型)一样,可以被保存。不同的地方是,在代理模型中进行的操作不会对原始模型产生影响

from django.db import models

calss Animal(models.Model):
    named = models.CharField(max_length=64)
    age = models.PositiveIntegerField()

class Cat(Animal):
    skill = models.CharField(max_length=32)    
    class Meta:
        ordering = ['age']  # 普通的Animal类是无序的,而Cat类会按照age进行排序
        proxy = True # 代理模型
from django.db import models

calss Animal(models.Model):
    named = models.CharField(max_length=64)
    age = models.PositiveIntegerField()
    class Meta:
        abstract = True

class Cat(Animal):
    object  = Animal()
    class Meta:
        proxy = True 

如果想要在代理类中添加新的管理器,而不是替换现有的默认管理器。那么可以创建一个含有新的管理器的基类,然后继承时,把该基类放在主基类的后面:

## 创建一个含有新的管理器的基类
class ExtraManagers(models.Model):
    secondary  = Animal()
    class Meta:
        abstract = True

class Cat(Animal, ExtraManagers):
    class Meta:
        prox = True
四、多重继承

多重继承并非是多表继承
Django中模型的多重继承和python的一样。如果模型类的多个父类都含有Meta类,则该子类只会继承第一个父类的Meta类
不推荐多重继承,因为很容易混乱

class Oldanimal(models.Model):
    old_id = models.AutoField(primary_key=True)  # 指定主键

class Newanimal(models.Model):
    new_id = models.AutoField(primary_key=True)  # 指定主键

class Cat(Newanimal, Oldanimal):
    pass
django.core.exceptions.FieldError: Local field 'name' in class 'yy' clashes with field of the same name from base class 'xx'.

当然,如果父类是一个抽象模型类就没问题了

五、用包来管理模型类

当我们生成一个app时,该app的目录下会自动生成一个models.py文件,我们就会在这个文件中创建这个app所需要的各种模型类。
但是,当模型类很多的时候,管理起来就不大方便,所以这个时候,我们可以把这些模型类分成各个py文件,使用包来管理这些模型类。

from .animal import Animal
from .cat import Cat
上一篇 下一篇

猜你喜欢

热点阅读