django orm的身份映射器
django-idmap的Python项目详细描述
版权所有2014-2017 Thomas Khyn 2009年大卫·克莱默
django orm的身份映射器。这是django-idmapper的叉子, 它不再被维护。
django-idmap已经针对django 1.8、1.11和2.0以及 Python2和3的最新次要版本(Django 2.0仅支持Python3)。
如果你喜欢django-gm2m,并且想办法感谢我和/或鼓励我 未来发展,这是我的BTC或BCH捐赠地址: 1EwENyR8RV6tMc1hsLTkPURtn5wJgaBfG9。
这是什么?
django-idmap是一个django应用程序,它:
- 第一次需要时,只在内存中加载一次实例
- 在整个口译员中共享它们,直到请求完成
实际上,默认的django行为是为 请求的开始和结束之间的数据库条目相同。它有一个 主要结果:如果需要,可以设置的临时属性将丢失 在代码的另一个位置访问相同的数据库对象。
警告
反序列化(例如从缓存)将not使用标识映射器。
使用django 1.8+和python 2和3的最新次要版本进行测试。
安装
尽可能简单,使用pip:
pip install django-idmap
您还需要将'idmap'添加到INSTALLED_APPS设置中。
快速启动
要为模型启用标识映射器,只需使其继承 从idmap.models.IdMapModel,而不是django.db.models.Model。
提示
您可以导入idmap.models,就像导入django.db.models一样。 idmap.models公开由django.db.modelsplus公开的所有内容 IdMapModel模型类。
当然,您可以混合和匹配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(...)
提供两种缓存模式:
- 弱引用模式:实例将在缓存中移除 不再提及它。这是默认行为
- 强引用模式:实例将只从 数据库,并将在刷新时从缓存中删除
如果要对特定模型使用强引用,只需设置 use_strong_refs到True在派生模型类Meta:
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 [...]
这样,instance1_1和数据库中的主键1将 与数据库中主键为1的instance2_1不同db2:
>>> 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是None,如果所有数据库都是 已刷新(即,如果未提供数据库别名)。
代理模型
全部安装使用同一基础混凝土类的模型和代理模型的NCES (我们称之为代理系列)存储在同一个缓存中,并且 可通过代理系列的所有成员访问:
>>> 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()