Package: django-idmap
© 2014-2017 Thomas Khyn
© 2009 David CramerAn identity mapper for the Django ORM. This is a fork ofdjango-idmapper,
which is no longer maintained.django-idmaphas been tested against django 1.8, 1.11 and 2.0 and the
latest minor versions of Python 2 and 3 (Django 2.0 only supports Python 3).If you like django-gm2m and are looking for a way to thank me and/or encourage
future development, here is my BTC or BCH donation address:1EwENyR8RV6tMc1hsLTkPURtn5wJgaBfG9.What is it?django-idmapis a Django application which:loads only once the instances in memory the first time they are neededshares them throughout your interpreter until the request is finishedIndeed, the default Django behavior is to expose different instances for the
same database entry between the start and the end of the request. It has one
main consequence: the temporary attributes you may set are lost if you want
to access the same database object in another place in your code.WarningDeserialization (such as from the cache) willnotuse the identity mapper.Tested with django 1.8+ and latest minor versions of python 2 and 3.InstallationAs straightforward as it can be, using pip:pip install django-idmapYou also need to add'idmap'to theINSTALLED_APPSsetting.Quick startTo enable the identity mapper for a model, you simply need to make it inherit
fromidmap.models.IdMapModelinstead ofdjango.db.models.Model.TipYou can importidmap.modelsas you would importdjango.db.models.idmap.modelsexposes all that is exposed bydjango.db.modelsplus
theIdMapModelmodel class.You may of course mix and matchIdMapModelandModel: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 caching modes are available:Weak references mode: the instance will be removed from the cache once there
are no more references to it. This is the default behaviorStrong references mode: the instance will be loaded only once from the
database and will be removed from the cache when it is flushedIf you want to use strong references for a particular model, simply setuse_strong_refstoTruein the derived model class’Meta:from idmap import models

class MyModel(models.IdMapModel):
   class Meta:
      use_strong_refs = True
   [...]Manual operationsIn most cases, that’s all there is to do withdjango-idmap. Sometimes, you
may need to flush the cache manually before the request is finished.You can use:idmap.flush()to erase the whole cacheIdMapModel.flush_instance_cache()to erase the cache for one modelIdMapModel.flush_cached_instance(instance)to erase one instance
from the cacheSignalsidmap.signals.pre_flushandidmap.signals.post_flushare sent before -
respectively after - the cache is flushed. Connect handlers to these if you
need to run code at these moments.django-idmapflushes the cache when therequest_finishedorpost_migratesignal are sent. This default behavior may be modified (at
your own risk!) by disconnecting theidmap.signals.flush_idmaphandler
from these signals.Multiple database supportIn some cases, you may need to store instances of the same model in several
databases. It is possible to telldjango-idmapto also take the database
into account when creating or getting instances:class MyModel(models.IdMapModel):
   class Meta:
      multi_db = True
   [...]This way,instance1_1with primary key1in databasedb1will be
different frominstance2_1with primary key1in databasedb2:>>> 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
AssertionErrorWhen using multiple databases, you may also flush only one database by
providing its name toidmap.flush():>>> idmap.flush('db1')will only flush instances that were retrieved using the databasedb1.IdMapModel.flush_instance_cachecan also take adbargument.Similarly, a keyword-argumentdbis provided when thepre_flushandpost_flushsignals are sent.dbisNoneif all databases are
flushed (i.e. if no database alias was provided).Proxy modelsAll instances of models and proxy models using the same base concrete class
(let’s call this a proxy family) are stored in the same cache, and are
accessible through all the members of the proxy family:>>> 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)Inheritance catch-upsIn case you need to use a custom manager or custom metaclass on a model based
onIdMapModel, you need to derive them fromidmap’s own manager and
metaclass:>>> class MyModelBase(models.IdMapModelBase):
>>>     [...]
>>> class MyManager(models.IdMapManager):
>>>     [...]
>>> class MyModel(models.IdMapModel,
                  metaclass=MyModelBase): # on python 3
>>>     __metaclass__ = MyModelBase  # on python 2
>>>     objects = MyManager()ReferencesDavid Cramer’sdjango-idmapperOriginal code and concept:http://code.djangoproject.com/ticket/17