Django ORM的身份映射器
项目描述
© 2014-2017 Thomas Khyn © 2009 David Cramer
这是Django ORM的身份映射器。这是对不再维护的django-idmapper的分支。
已针对django 1.8、1.11和2.0以及Python 2和3的最新次要版本(仅Django 2.0支持Python 3)进行测试。
如果你喜欢django-gm2m,并想感谢我/鼓励未来的开发,以下是我的BTC或BCH捐赠地址:1EwENyR8RV6tMc1hsLTkPURtn5wJgaBfG9。
这是什么?
django-idmap是一个Django应用程序,
首次需要时在内存中仅加载一次实例
在整个解释器中共享,直到请求完成
实际上,Django的默认行为是在请求的开始和结束之间暴露不同的实例。这有一个主要后果:如果你想在代码的另一个地方访问相同的数据库对象,你设置的临时属性将会丢失。
已与django 1.8+以及python 2和3的最新次要版本进行测试。
安装
使用pip,尽可能简单
pip install django-idmap
您还需要将'idmap'添加到INSTALLED_APPS设置中。
快速入门
要启用模型的身份映射器,您只需将其继承自 idmap.models.IdMapModel 而不是 django.db.models.Model 即可。
当然,您可以将 IdMapModel 和 Model 混合使用。
from idmap import models class MyModel(models.IdMapModel): name = models.CharField(...) fkey = models.ForeignKey('Other', on_delete=models.CASCADE) class Other(models.Model): name = models.CharField(...)
有 2 种缓存模式可用
弱引用模式:一旦没有更多的引用指向它,实例将从缓存中删除。这是默认行为。
强引用模式:实例将只从数据库加载一次,并在刷新时从缓存中删除。
如果您想为特定模型使用强引用,只需在派生模型类的 Meta 中将 use_strong_refs 设置为 True 即可。
from idmap import models class MyModel(models.IdMapModel): class Meta: use_strong_refs = True [...]
手动操作
在大多数情况下,这就是使用 django-idmap 所要做的。有时,在请求完成之前,您可能需要手动刷新缓存。
您可以使用
idmap.flush() 来清除整个缓存
IdMapModel.flush_instance_cache() 来清除一个模型的缓存
IdMapModel.flush_cached_instance(instance) 来从缓存中清除一个实例
信号
idmap.signals.pre_flush 和 idmap.signals.post_flush 分别在缓存刷新之前和之后发送。如果需要在这些时刻运行代码,请将这些处理程序连接到这些信号。
django-idmap 在发送 request_finished 或 post_migrate 信号时刷新缓存。可以通过断开 idmap.signals.flush_idmap 处理程序与这些信号的联系来修改此默认行为(风险自担!)。
多数据库支持
在某些情况下,您可能需要将同一模型的实例存储在多个数据库中。您可以让 django-idmap 在创建或获取实例时也考虑数据库。
class MyModel(models.IdMapModel): class Meta: multi_db = True [...]
这样,数据库 db1 中主键为 1 的 instance1_1 将与数据库 db2 中主键为 1 的 instance2_1 不同。
>>> MyModel.objects.using('db1').create(pk=1) >>> MyModel.objects.using('db2').create(pk=1) >>> idmap.flush() >>> instance1_1 = MyModel.objects.using('db1').get(pk=1) >>> instance2_1 = MyModel.objects.using('db2').get(pk=1) >>> assert instance1_1 is instance 2_1 AssertionError
在使用多个数据库时,您也可以通过向 idmap.flush() 提供数据库名称来仅刷新一个数据库。
>>> idmap.flush('db1')
这将仅刷新使用数据库 db1 获取的实例。 IdMapModel.flush_instance_cache 也可以接受一个 db 参数。
同样,当发送 pre_flush 和 post_flush 信号时,提供了一个关键字参数 db。如果刷新所有数据库(即如果没有提供数据库别名),则 db 为 None。
代理模型
使用相同的基础具体类(我们称之为代理族)的所有模型和代理模型的实例都存储在同一个缓存中,并且可以通过代理族的成员访问。
>>> class MyProxyModel(MyModel): >>> class Meta: >>> proxy = True >>> original = MyModel.objects.create(pk=1) >>> proxy = MyProxyModel.objects.create(pk=2) >>> assert original is MyProxyModel.get(pk=1)
继承追击
如果您需要在基于 IdMapModel 的模型上使用自定义管理器或自定义元类,则需要从 idmap 的自己的管理器和元类派生它们。
>>> class MyModelBase(models.IdMapModelBase): >>> [...] >>> class MyManager(models.IdMapManager): >>> [...] >>> class MyModel(models.IdMapModel, metaclass=MyModelBase): # on python 3 >>> __metaclass__ = MyModelBase # on python 2 >>> objects = MyManager()
参考
David Cramer 的 django-idmapper
项目详情
django-idmap-1.0.3.tar.gz 的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | 0b067d0f101c97f35ed14c244a69bf4dfe1c138a99a55717ed345323c5af3163 |
|
MD5 | d0a78369460b985552b720760ffe3189 |
|
BLAKE2b-256 | 7d281658c8d12807b2138d0a7dc15b6c9cf70b99860609ba9973081d8f2b5403 |