抽象基类 ( Abstract base classes)
抽象基类
当你想将一些共有信息放进其它一些model的时候,抽象化类是十分有用的。你编写完基类之后,在 Meta类中设置 abstract=True ,这个模型就不会被用来创建任何数据表。取而代之的是,当它被用来作为一个其他model的基类时,它的字段将被加入那些子类中。如果抽象基类和它的子类有相同的字段名,那么将会出现error(并且Django将抛出一个exception)。
一个例子:
from django.db import models class CommonInfo(models.Model): name = models.CharField(max_length=100) age = models.PositiveIntegerField() class Meta: abstract = True class Student(CommonInfo): home_group = models.CharField(max_length=5)
Student 模型将有三个项:name, age 和 home_group。CommonInfo 模型无法像一般的Django模型一样使用,因为它是一个抽象基类。它无法生成一张数据表或者拥有一个管理器,并且不能实例化或者直接储存。
许多应用场景下, 这种类型的模型继承恰好是你想要的。它提供一种在 Python 语言层级上提取公共信息的方式,同时在数据库层级上,每个子类各自仍然只创建一个数据库表。
第二个例子:
from django.contrib.auth.models import AbstractUser class UserProfile(AbstractUser): nick_name = models.CharField(max_length=20, verbose_name=u"昵称", default=u"") birthday = models.DateField(verbose_name=u"生日", null=True, blank=True) gender = models.CharField(max_length=6, choices=(("male", u"男"), ("female", u"女")), default="female") address = models.CharField(max_length=100, default=u"") mobile = models.CharField(max_length=11, null=True, blank=True) image = models.ImageField(upload_to="image/%Y/%m", default=u"image/default.png", max_length=100) class Meta: verbose_name = u"用户信息" verbose_name_plural = verbose_name def __str__(self): return self.username
UserProfile模型继承至 AbstractUser, 以此来扩展默认的User表。
不许“重写”字段
普通的 Python 类继承允许子类覆盖父类的任何属性。 但在 Django 中,重写 Field实例是不允许的(至少现在还不行)。如果基类中有一个 author字段,你就不能在子类中创建任何名为 author的字段。
重写父类的字段会导致很多麻烦,比如:初始化实例(指定在 Model.__init__ 中被实例化的字段) 和序列化。而普通的 Python 类继承机制并不能处理好这些特性。所以 Django 的继承机制被设计成与 Python 有所不同,这样做并不是随意而为的。

浙公网安备 33010602011771号