Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1102490
  • 博文数量: 1310
  • 博客积分: 3980
  • 博客等级: 中校
  • 技术积分: 8005
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-09 22:05
文章分类

全部博文(1310)

文章存档

2011年(1)

2008年(1309)

我的朋友

分类:

2008-11-09 16:01:37

今天看到一篇关于介绍Django继承机制的帖子,虽然简单,但是还是记下来,以免忘记:
django 的继承有两种方式:
第一种:将父类声明为abstract,这样每个具体的子类均有一个对应的表,父类是抽象类,不会为之建表
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(10NOT NULL,
    `height` 
smallint NOT NULL,
    `makeup` 
varchar(20NOT NULL
)
;
CREATE TABLE `sample_man` (
    `id` 
integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `name` 
varchar(10NOT NULL,
    `height` 
smallint NOT NULL,
    `job` 
varchar(20NOT NULL
)
;
COMMIT;

第二种:
基类一个表,每个子类的扩展属性另一个表,写法上没有什么特别要求
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(10NOT NULL,
    `height` 
smallint NOT NULL
)
;
CREATE TABLE `sample_woman` (
    `person_ptr_id` 
integer NOT NULL UNIQUE PRIMARY KEY,
    `makeup` 
varchar(20NOT 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(20NOT 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两个属性,下面的结论摘自我在邮件列表中的答复,备忘用

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

(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. 






seal 2008-10-28 22:42 发表评论
阅读(317) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~