今天看到一篇关于介绍Django继承机制的帖子,虽然简单,但是还是记下来,以免忘记:
django 的继承有两种方式:
第一种:将父类声明为abstract,这样每个具体的子类均有一个对应的表,父类是抽象类,不会为之建表
 from django.db import models
from django.db import models

 # Create your models here.
# Create your models here.
 class Person(models.Model):
class Person(models.Model): 
 name = models.CharField(max_length=10)
        name = models.CharField(max_length=10) 
 height = models.SmallIntegerField()
        height = models.SmallIntegerField() 
 class Meta:
    class Meta:
 abstract=True
        abstract=True
 
  

 class Man(Person):
class Man(Person): 
 job = models.CharField(max_length=20)
        job = models.CharField(max_length=20) 


 class Woman(Person):
class Woman(Person): 
 makeup = models.CharField(max_length=20)
        makeup = models.CharField(max_length=20) 

通过在Meta类中声明abstract=True,标识Person为抽象基类,这个类没有objects属性,也就是说没有Manager方法,无法进行单独的数据操作,所有的数据操作都要通过子类进行
生成的sql语句如下
 BEGIN;
BEGIN;
 CREATE TABLE `sample_woman` (
CREATE TABLE `sample_woman` (
 `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
 `name` varchar(10) NOT NULL,
    `name` varchar(10) NOT NULL,
 `height` smallint NOT NULL,
    `height` smallint NOT NULL,
 `makeup` varchar(20) NOT NULL
    `makeup` varchar(20) NOT NULL
 )
)
 ;
;
 CREATE TABLE `sample_man` (
CREATE TABLE `sample_man` (
 `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
 `name` varchar(10) NOT NULL,
    `name` varchar(10) NOT NULL,
 `height` smallint NOT NULL,
    `height` smallint NOT NULL,
 `job` varchar(20) NOT NULL
    `job` varchar(20) NOT NULL
 )
)
 ;
;
 COMMIT;
COMMIT;
第二种:
基类一个表,每个子类的扩展属性另一个表,写法上没有什么特别要求
 from django.db import models
from django.db import models

 # Create your models here.
# Create your models here.
 class Person(models.Model):
class Person(models.Model): 
 name = models.CharField(max_length=10)
        name = models.CharField(max_length=10) 
 height = models.SmallIntegerField()
        height = models.SmallIntegerField() 


 class Man(Person):
class Man(Person): 
 job = models.CharField(max_length=20)
        job = models.CharField(max_length=20) 


 class Woman(Person):
class Woman(Person): 
 makeup = models.CharField(max_length=20)
        makeup = models.CharField(max_length=20) 

生成的sql如下
 BEGIN;
BEGIN;
 CREATE TABLE `sample_person` (
CREATE TABLE `sample_person` (
 `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
 `name` varchar(10) NOT NULL,
    `name` varchar(10) NOT NULL,
 `height` smallint NOT NULL
    `height` smallint NOT NULL
 )
)
 ;
;
 CREATE TABLE `sample_woman` (
CREATE TABLE `sample_woman` (
 `person_ptr_id` integer NOT NULL UNIQUE PRIMARY KEY,
    `person_ptr_id` integer NOT NULL UNIQUE PRIMARY KEY,
 `makeup` varchar(20) NOT NULL
    `makeup` varchar(20) NOT NULL
 )
)
 ;
;
 ALTER TABLE `sample_woman` ADD CONSTRAINT person_ptr_id_refs_id_4baa7c33 FOREIGN
ALTER TABLE `sample_woman` ADD CONSTRAINT person_ptr_id_refs_id_4baa7c33 FOREIGN
 KEY (`person_ptr_id`) REFERENCES `sample_person` (`id`);
 KEY (`person_ptr_id`) REFERENCES `sample_person` (`id`);
 CREATE TABLE `sample_man` (
CREATE TABLE `sample_man` (
 `person_ptr_id` integer NOT NULL UNIQUE PRIMARY KEY,
    `person_ptr_id` integer NOT NULL UNIQUE PRIMARY KEY,
 `job` varchar(20) NOT NULL
    `job` varchar(20) NOT NULL
 )
)
 ;
;
 ALTER TABLE `sample_man` ADD CONSTRAINT person_ptr_id_refs_id_78ed52db FOREIGN K
ALTER TABLE `sample_man` ADD CONSTRAINT person_ptr_id_refs_id_78ed52db FOREIGN K
 EY (`person_ptr_id`) REFERENCES `sample_person` (`id`);
EY (`person_ptr_id`) REFERENCES `sample_person` (`id`);
 CREATE UNIQUE INDEX `sample_woman_person_ptr_id` ON `sample_woman` (`person_ptr_
CREATE UNIQUE INDEX `sample_woman_person_ptr_id` ON `sample_woman` (`person_ptr_
 id`);
id`);
 CREATE UNIQUE INDEX `sample_man_person_ptr_id` ON `sample_man` (`person_ptr_id`)
CREATE UNIQUE INDEX `sample_man_person_ptr_id` ON `sample_man` (`person_ptr_id`)
 ;
;
 COMMIT;
COMMIT;Person类可以进行数据查询操作,所以有必要识别返回的类是什么的问题,这里isinstance没用,django的处理是为Person添加子类的属性,以方便你通过这些属性访问具体的子类,在这里
results=Person.objects.all()
r=results[0]
这个r就有woman和man两个属性,下面的结论摘自我在邮件列表中的答复,备忘用
 这时,person_obj有 man和person两个属性
这时,person_obj有 man和person两个属性 
 如果访问一个不是属于该类型的就会出现DoesNotExist 异常
如果访问一个不是属于该类型的就会出现DoesNotExist 异常 
 实际中,不用通过捕获异常去判断,直接用
实际中,不用通过捕获异常去判断,直接用 
 hasattr(person_obj,'man') 或 hasattr(person_obj,'woman') 就可以判断,返回True的就是
hasattr(person_obj,'man') 或 hasattr(person_obj,'woman') 就可以判断,返回True的就是 
 目标类型
目标类型 

 (InteractiveConsole)
(InteractiveConsole) 


 >>> from sample.models import *
>>> from sample.models import * 
 >>> results=Person.objects.all()
>>> results=Person.objects.all() 
 >>> r=results[0]
>>> r=results[0] 
 >>> hasattr(r,'woman')
>>> hasattr(r,'woman') 
 False
False 
 >>> hasattr(r,'man')
>>> hasattr(r,'man') 
 True
True 
 >>> r.man.job
>>> r.man.job 
 u'computer'
u'computer' 
 >>> r.woman
>>> r.woman 


 Traceback (most recent call last):
Traceback (most recent call last): 
 File "<console>", line 1, in <module>
  File "<console>", line 1, in <module> 
 File "C:"Python25"Lib"site-packages"django"db"models"fields
  File "C:"Python25"Lib"site-packages"django"db"models"fields 
 "related.py", line
"related.py", line 
 178, in __get__
178, in __get__ 
 rel_obj = self.related.model._default_manager.get(**params)
    rel_obj = self.related.model._default_manager.get(**params) 
 File "C:"Python25"Lib"site-packages"django"db"models"manager.py",
  File "C:"Python25"Lib"site-packages"django"db"models"manager.py", 
 line 82, in
line 82, in 
 get
get 
 return self.get_query_set().get(*args, **kwargs)
    return self.get_query_set().get(*args, **kwargs) 
 File "C:"Python25"Lib"site-packages"django"db"models"query.py", line
  File "C:"Python25"Lib"site-packages"django"db"models"query.py", line 
 197, in g
197, in g 
 et
et 
 % self.model._meta.object_name)
    % self.model._meta.object_name) 
 DoesNotExist: Woman matching query does not exist.
DoesNotExist: Woman matching query does not exist. 

