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

from django.db import models

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


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


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

通过在Meta类中声明abstract=True,标识Person为抽象基类,这个类没有objects属性,也就是说没有Manager方法,无法进行单独的数据操作,所有的数据操作都要通过子类进行
生成的sql语句如下

BEGIN;
CREATE TABLE sample_woman (
id
integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
name
varchar(10) NOT NULL,
height
smallint NOT NULL,
makeup
varchar(20) NOT NULL
)
;
CREATE TABLE sample_man (
id
integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
name
varchar(10) NOT NULL,
height
smallint NOT NULL,
job
varchar(20) NOT NULL
)
;
COMMIT;

第二种:
基类一个表,每个子类的扩展属性另一个表,写法上没有什么特别要求<br />

from django.db import models

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


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


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

生成的sql如下

BEGIN;
CREATE TABLE sample_person (
id
integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
name
varchar(10) NOT NULL,
height
smallint NOT NULL
)
;
CREATE TABLE sample_woman (
person_ptr_id
integer NOT NULL UNIQUE PRIMARY KEY,
makeup
varchar(20) NOT NULL
)
;
ALTER TABLE sample_woman ADD CONSTRAINT person_ptr_id_refs_id_4baa7c33 FOREIGN
KEY (person_ptr_id) REFERENCES sample_person (id);
CREATE TABLE sample_man (
person_ptr_id
integer NOT NULL UNIQUE PRIMARY KEY,
job
varchar(20) NOT NULL
)
;
ALTER TABLE sample_man ADD CONSTRAINT person_ptr_id_refs_id_78ed52db FOREIGN K
EY (person_ptr_id)
REFERENCES sample_person (id);
CREATE UNIQUE INDEX sample_woman_person_ptr_id ON sample_woman (person_ptr_
id
);
CREATE UNIQUE INDEX sample_man_person_ptr_id ON sample_man (person_ptr_id)
;
COMMIT;

Person类可以进行数据查询操作,所以有必要识别返回的类是什么的问题,这里isinstance没用,django的处理是为Person添加子类的属性,以方便你通过这些属性访问具体的子类,在这里
results=Person.objects.all()
r=results[0]
这个r就有woman和man两个属性,下面的结论摘自我在邮件列表中的答复,备忘用<br />

这时,person_obj有&nbsp;man和person两个属性&nbsp;
如果访问一个不是属于该类型的就会出现DoesNotExist 异常
实际中,不用通过捕获异常去判断,直接用&nbsp;
hasattr(person_obj,’man’) 或&nbsp;hasattr(person_obj,’woman’) 就可以判断,返回True的就是&nbsp;
目标类型

(InteractiveConsole)


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


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


Leave a Reply

电子邮件地址不会被公开。 必填项已用*标注