Django 面向对象orm

django支持三种风格的模型继承:

1. 抽象类继承: 父类继承自models.Model, 但不会在数据库中生成相应的数据表。父类的属性列存储在其子类的数据表中

2. 多表继承: 多表继承的每个类都在数据库中生成相应的数据表管理数据

3. 代理模型继承: 父类用于在数据库中管理数据表, 子类不定义数据列,只定义查询的数据集的排序方式等元数据

 

抽象类继承

抽象类继承的作用是在多个表中有若干相同字段时,可以将这些字段统一定义在抽象基类中,免于重复定义这些字段

from django.db import models

class MessageBase(models.Model):
    id = models.AutoField()
    content = models.CharField(max_length=100)
    user_name = models.CharField(max_length=80)
    pub_date = models.DateField()
    
    class Meta:
        abstract = True      #定义本类为抽象类
        
class Moment(MessageBase):
    headline = models.CharField(max_length=50)
    
LEVELS = (
    ('1', 'Very Good'),
    ('2', 'Good'),
    ('3', 'Normal'),
    ('4', 'Bad'),
)

class Comment(MessageBase):
    level = models.CharField(max_length=1, choices=LEVELS)

映射到数据库后,会建立两个数据表

moment:   字段有 id, content, user_name, pub_date, headline

comment:  字段有id, content, user_name, pub_date, level

多表继承

在多表继承中,无论是父表还是子表都会用数据库中对应的数据表维护模型数据;父类的字段不会重复地在多个子类的数据表中定义

from django.db import models

class MessageBase(models.Model):
    id = models.AutoField()
    content = models.CharField(max_length=100)
    user_name = models.CharField(max_length=80)
    pub_date = models.DateField()
    
class Moment(MessageBase):
    headline = models.CharField(max_length=50)
    
class Comment(MessageBase):
    level = models.CharField(max_lenght=1, choices=LEVELS)

数据库中实际会生成3个数据表:

MessageBase:   字段有 id, content, user_name, pub_date

Moment: 字段有 id, headline

Comment: 字段有 id, level

而在实际应用 中,子类仍然可以直接引用父类定义的字段, 同时子类可以通过父类对象引用访问父类实例

m1 = Moment(user_name='Terry', headline='Hello World')
m1.content = "reference parent field in subclass"
m1.save()

print m1.messagebase.content    #通过小写的父类名可以引用父类的实例

代理模型继承

代理模型中的子类只用于管理父类的数据,而不实际存储数据;代理模型继承通过在子类的Meta中定义proxy=True实现

from django.db import models

class Moment(models.Model):
    id = models.AutoField()
    headline = models.CharField(max_lenght=50)
    content = models.CharField(max_lenght=100)
    user_name = models.CharField(max_lenght=80)
    pub_date = models.DateField()
    
class OrderedMoment(Moment):
    class Meta:
        proxy = True
        ordering = ["-pub_date"]
父类模型用于存储数据,子类模型用于管理根据Pub_date倒序排序。  这样子类中的新特性,不会影响父类模型及其已有的代码。
posted @ 2017-01-12 22:25  黄小墨  阅读(1392)  评论(0编辑  收藏  举报