Django 多态模型
快速入门、文档、贡献
What is django_polymorphic good for?_Quickstart,或完整的Installation and Usage DocsRelease Notes, News and Discussion(Google Group)或 Changelog- 从 GitHub_ 或 Bitbucket_ 下载,或以 TGZ_ 或 ZIP_ 形式下载
- 改进 django_polymorphic,报告问题,讨论,提交补丁或 fork(GitHub_、Bitbucket_、Group_、Mail_)
.. _What is django_polymorphic good for?: #good-for .. _release notes, news and discussion: http://groups.google.de/group/django-polymorphic/topics .. _Group: http://groups.google.de/group/django-polymorphic/topics .. _Mail: http://github.com/bconstantin/django_polymorphic/tree/master/setup.py .. _Installation and Usage Docs: http://bserve.webhop.org/django_polymorphic/DOCS.html .. _Quickstart: http://bserve.webhop.org/django_polymorphic/DOCS.html#quickstart .. _GitHub: http://github.com/bconstantin/django_polymorphic .. _Bitbucket: http://bitbucket.org/bconstantin/django_polymorphic .. _TGZ: http://github.com/bconstantin/django_polymorphic/tarball/master .. _ZIP: http://github.com/bconstantin/django_polymorphic/zipball/master .. _Overview: http://bserve.webhop.org/django_polymorphic .. _Changelog: http://bserve.webhop.org/django_polymorphic/CHANGES.html
.. _good-for:
django_polymorphic 适用于什么场景?
假设模型 ArtProject and ResearchProject 派生
自模型 Project,并将每种模型各存储一个到数据库中:
Project.objects.create(topic="Department Party") ArtProject.objects.create(topic="Painting with Tim", artist="T. Turner") ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")
如果我们想检索所有的项目,我们执行:
Project.objects.all()
使用 django_polymorphic,我们简单地获取我们存储的内容::
[ <Project: id 1, topic "Department Party">,
<ArtProject: id 2, topic "Painting with Tim", artist "T. Turner">,
<ResearchProject: id 3, topic "Swallow Aerodynamics", supervisor "Dr. Winter"> ]
使用原生 Django,我们得到的是不完整的对象,这很可能不是我们想要的::
[ <Project: id 1, topic "Department Party">,
<Project: id 2, topic "Painting with Tim">,
<Project: id 3, topic "Swallow Aerodynamics"> ]
ForeignKeys、ManyToManyFields 或 OneToOneFields 的情况也非常相似。
总体而言,django_polymorphic 的作用有两方面:
一方面,它确保模型继承能够按预期正常工作,通过简单地保证你从数据库中取回的始终是你存储的完全相同的对象——无论以何种方式访问它们,从而使模型继承更加“pythonic”。 这可以为你省去许多令人不快的变通方法,这些方法往往会使代码变得杂乱、易出错且缓慢。
另一方面,配合 Django ORM 的一些小型 API 扩展,django_polymorphic 支持了一种更具表达力和直观性的编程风格,同时也支持了原生 Django 无法实现的非常高级的面向对象设计。
幸运的是,实现此功能所需的大部分繁重机制已经存在于原始的 Django 数据库层中。 Django_polymorphic 在其上方添加了一个相当薄的层,以使真正的 OO 完全自动化且易于使用。
然而有一个陷阱,这适用于具体的模型继承:当前的 DBM 系统如 PostgreSQL 或 MySQL 在处理所需的 sql 查询方面表现不佳,在许多情况下可能相当缓慢。具体的基准测试即将发布(请参阅讨论论坛)。
欲了解更多信息,请查看 Quickstart_ 或完整的 Installation and Usage Docs,并参见 restrictions and caveats。
.. _restrictions and caveats: http://bserve.webhop.org/django_polymorphic/DOCS.html#restrictions
这是 V1.0 测试版/测试发布
该版本包含软件中一些更关键部分的相当多的更改。它旨在用于测试和开发环境,而非生产环境。对于这些环境,最好等待几周,以便为正式的 V1.0 版本留出时间,让任何潜在问题(如果存在)得以显现。
如果您在使用 API 或本次测试版中的更改时遇到任何问题或有建议,请在 discussion group_
中发布,或在 GitHub_ 或 BitBucket_ 上提交 issue(或给我发送电子邮件)。
.. _discussion group: http://groups.google.de/group/django-polymorphic/topics
许可证
Django_polymorphic 使用与 Django 相同的许可证(类 BSD)。
API 变更与新增
2010 年 11 月 11 日,V1.0 API 变更
extra() queryset 方法 +++++++++++++++++++++++
.extra() 已重新实现。现在它默认是多态的,并且(几乎)没有限制地工作(请参阅文档)。这是相对于 django_polymorphic 之前版本的(非常)不兼容的 API 变更。
对 polymorphic 关键字参数的支持已被移除。
您可以通过使用 ModelA.objects.non_polymorphic().extra() 来恢复非多态行为。
默认情况下不对 Querysets 进行美化打印 ++++++++++++++++++++++++++++++++++++++++++
为了改善与原生 Django 的兼容性,打印查询集 (repr 和 unicode)默认不再使用 django_polymorphic 的漂亮打印。 若要恢复打印查询集时的旧行为, 你需要将模型定义替换为:
class Project(PolymorphicModel):
替换为:
class Project(PolymorphicModel, ShowFieldType):
用于漂亮输出的混入类已重命名:
``ShowFieldTypes, ShowFields, ShowFieldsAndTypes``
现在是:
``ShowFieldType, ShowFieldContent and ShowFieldTypeAndContent``
(旧版本仍保留以兼容)
Pretty-Printing 输出格式已更改 +++++++++++++++++++++++++++++++++++++
ShowFieldContent and ShowFieldTypeAndContent 现在
使用略有不同的输出格式。如果这给
你的测试用例带来太多麻烦,你可以通过在
模型定义中添加 polymorphic_showfield_old_format = True 来(大致)恢复旧行为。
ShowField... 现在也为自定义
主键生成更具信息量的输出。
polymorphic_dumpdata ++++++++++++++++++++
polymorphic_dumpdata 管理命令不再需要
并且已被禁用,因为标准的 Django dumpdata 命令现在可以自动
正确支持多态模型(适用于所有受支持的 Django 版本)。
使用 Django 1.3 运行测试套件 ++++++++++++++++++++++++++++++++++++++
Django 1.3 需要 python manage.py test polymorphic 而不是
仅仅 python manage.py test。
2010 年 11 月 01 日,V1.0 API 新增
-
添加了
.non_polymorphic()queryset 成员函数。这比 使用.base_objects...更优,因为它仅使生成的 queryset 变为非多态 且不改变所用 manager 的其他行为(而.base_objects只是一个不同的 manager)。 -
.get_real_instances()已提升为 API 的正式组成部分。 它允许你将 queryset 或基础对象列表转换为真实实例的列表。 这在例如使用ModelA.objects.non_polymorphic().extra(...)后希望 将结果转换为其多态等价形式时非常有用:
qs = ModelA.objects.all().non_polymorphic() >>> real_objects = qs.get_real_instances()
等价于:
>>> real_objects = ModelA.objects.all()
也可以使用 ``qs.get_real_instances()``, ``ModelA.objects.get_real_instances(qs)``。在后一种情况下,``qs`` 可以是任何 ModelA 类型对象的列表。
translate_polymorphic_Q_object(参见 DOCS)
2010 年 2 月 22 日,安装说明
django_polymorphic 的源代码已重新组织, 因此需要像普通的 Django App 一样进行安装
- 要么将 "polymorphic" 目录复制到您的 Django 项目中,要么运行 setup.py。不过,在 settings.py 的 INSTALLED_APPS 中添加 'polymorphic' 仍然是可选的。
文件 polymorphic.py 不能再作为独立的
扩展模块使用(因为它已被拆分为多个
较小的文件)。
导入方式现在略有不同:所有相关符号都 直接从 'polymorphic' 导入,而不是从 'polymorphic.models' 导入::
# 新方式
from polymorphic import PolymorphicModel, ...
# 旧方式,不再有效
from polymorphic.models import PolymorphicModel, ...
2010 年 1 月 26 日:数据库架构变更
1 月 26 日的更新更改了数据库架构(更多信息见 commit-log_)。 对造成的不便深表歉意。但这应该是最终的数据库架构了。
.. _commit-log: http://github.com/bconstantin/django_polymorphic/commit/c2b420aea06637966a208329ef7ec853889fa4c7