{{{
#!python
def get_points_earned(account):
key = 'acct-{0}-points'.format(account.id)
if not cache.get(key):
point_awards = PointAward.objects.filter(account=account)
points = point_awards.aggregate(total=Sum('points'))['total']
cache.set(key, points)
return cache.get(key)
# Invalidate points earned if a PointAward is added/changed/deleted
@receiver([post_save, post_delete, post_update], sender=PointAward)
def on_point_award_changed(sender, **kwargs):
instance = kwargs.get('instance')
if instance:
key = 'acct-{0}-points'.format(instance.id)
cache.delete(key)
}}}
With this coherence strategy, a call to `PointAward.objects.update()` will
cause the cache to become incoherent, and will cause errors in the
calculation.
This can easily be addressed by providing a signal allowing a developer
to decide how best to update the cache when `update()` is called:
{{{
#!python
# django/db/models/signals.py
pre_update = ModelSignal(providing_args=["queryset", "values", "using"],
use_caching=True)
post_update = ModelSignal(providing_args=["queryset", "values", "using"],
use_caching=True)
}}}
We can now update our receiver to also respond to updates as well as
changes and deletions:
{{{
#!python
@receiver([post_save, post_delete], sender=PointAward)
def on_point_award_changed(sender, **kwargs):
point_award = kwargs.get('instance')
if instance and instance.pk:
# this is a save/delete, invalidate the related account's points
account_id = point_award.account_id
key = 'acct-{0}-points'.format(instance.id)
cache.delete(key)
elif kwargs.get('queryset'):
# this is an update, invalidate all matching accounts
qs = kwargs['queryset']
for acct_id in qs.objects.distinct().values_list('account_id',
flat=True)
key = 'acct-{0}-points'.format(acct_id)
cache.delete(key)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/22543>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* status: new => closed
* needs_better_patch: => 0
* resolution: => duplicate
* needs_tests: => 0
* needs_docs: => 0
Comment:
Hi @bendavis78, this feature is discussed at #21461.
--
Ticket URL: <https://code.djangoproject.com/ticket/22543#comment:1>
* resolution: duplicate => wontfix
Comment:
Seems this is similar to #17824 which was won't fixed. Needs discussion on
the django-developers mailing list in order to be accepted.
--
Ticket URL: <https://code.djangoproject.com/ticket/22543#comment:2>