django中 分别获取父类子类 对象

本文介绍了一个使用 Django 的 ORM 功能实现继承的例子,通过定义基类和子类来展示如何为不同类型的对象(如文章、照片和链接)提供统一的父类接口。这种设计可以简化查询操作,使得从父类查询子类实例变得更加直观。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[code]
from django.db import models
from django.db.models.query import QuerySet


class ChildQuerySet(QuerySet):
def iterator(self):
for obj in super(ChildQuerySet, self).iterator():
yield obj.get_child_object()


class ChildManager(models.Manager):
def get_query_set(self):
return ChildQuerySet(self.model)


class ParentModel(models.Model):
_child_name = models.CharField(max_length=100, editable=False)

class Meta:
abstract = True

def save(self, *args, **kwargs):
self._child_name = self.get_child_name()
super(ParentModel, self).save(*args, **kwargs)

def get_child_name(self):
if type(self) is self.get_parent_model():
return self._child_name
return self.get_parent_link().related_query_name()

def get_child_object(self):
return getattr(self, self.get_child_name())

def get_parent_link(self):
return self._meta.parents[self.get_parent_model()]

def get_parent_model(self):
raise NotImplementedError

def get_parent_object(self):
return getattr(self, self.get_parent_link().name)

[/code]
用法:
[code]
class Post(ParentModel):
title = models.CharField(max_length=50)

objects = models.Manager()
children = ChildManager()

def __unicode__(self):
return self.title

def get_parent_model(self):
return Post

class Article(Post):
text = models.TextField()

class Photo(Post):
image = models.ImageField(upload_to='photos/')

class Link(Post):
url = models.URLField()


输出:
>>> Post.objects.all()
[<Post: Django>, <Post: Make a Tumblelog>, <Post: Self Portrait>]

>>> Post.children.all()
[<Link: Django>, <Article: Make a Tumblelog>, <Photo: Self Portrait>]
[/code]
### Django 中 ForeignKey 在 models 中的用法 在 Django 的 ORM (对象关系映射) 中,`ForeignKey` 是用来表示一对多的关系。这意味着一个父类对象可以有多个子类对象与其关联,而每个子类对象仅能有一个对应的父类对象。 #### 定义 ForeignKey 关系 当定义 `ForeignKey` 时,通常是在被关联的一方指定该字段来指向另一张表中的记录: ```python from django.db import models class Author(models.Model): name = models.CharField(max_length=100) class Book(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey(Author, on_delete=models.CASCADE) ``` 在这个例子中,每本书 (`Book`) 都会有关联到一位作者 (`Author`) 的外键[^1]。 #### 设置删除行为 `on_delete` 参数指定了当所引用的对象被删除时应采取的动作。常见的选项包括: - `CASCADE`: 当父级对象被删除时自动删除所有依赖于它的子级对象; - `PROTECT`: 如果存在任何子级对象,则阻止父级对象的删除操作; - `SET_NULL`: 将外键设为空值(null),前提是允许此列可空; - `SET_DEFAULT`: 设定默认值作为新的外键目标,默认情况下不会改变现有数据; - `DO_NOTHING`: 不做处理,可能会违反数据库约束条件,在某些场景下不推荐使用。 #### 使用反向管理器访问相关对象 一旦建立了 `ForeignKey` 关系,就可以利用自动生成的相关管理器轻松获取或修改关联的数据集。对于上述案例而言,可以通过如下方式获得某位作家的所有书籍列表: ```python author_instance.book_set.all() ``` 这里 `book_set` 即为由 `Book` 表生成并连接至 `Author` 实例上的反向管理器名称;当然也可以通过设置 `related_name` 属性来自定义这个属性的名字。 #### 可选参数及相关配置 除了基本的功能之外,还可以进一步定制化 `ForeignKey` 字段的行为,比如设定是否允许为空(`null=True/False`)、唯一性约束(`unique=True/False`)以及索引优化等特性。 ```python publisher = models.ForeignKey(Publisher, null=True, blank=True, unique=False, db_index=True, related_name='books', on_delete=models.SET_NULL) ``` 这段代码片段展示了更多可用的选择项及其含义。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值