0

I cannot seem to cache changes I make to fields of a Django model. I understand that the reason is that I am only ever changing copies of those fields. But I don't know what to do about it.

Consider this trivial example (the real code is much more complex, but I believe this isolates the issue):

models.py:

class Parent(models.Model):
    name = models.CharField(blank=True, max_length=BIG_STRING, unique=True)

class Child(models.Model):
    name = models.CharField(blank=True, max_length=BIG_STRING, unique=True)
    parent = models.ForeignKey("Parent", blank=True, null=True, related_name="children")

Now someplace in my code I create a hierarchy of models and then cache it (using memcached):

view1.py:

parent = Parent(name="parent")
child = Child(name="child1")
parent.save()
child.save()
parent.children.add(child)
cache = caches["default"]
cache.set("my_unique_key", parent)

So far, so good. Elsewhere in my code I retrieve my cached object and make some changes to it and then re-cache it. But those changes are not saved:

view2.py:

cache = caches["default"]
parent = cache.get("my_unique_key")
local_copy_of_child = parent.children.get(name="child1")
local_copy_of_child.name = "child2"
cache.set("my_unique_key", parent)

Obviously the value of parent.children.all()[0].name is "child1" instead of "child2".

But, in the real code, the location of the instance I want to change is arbitrarily complex (it could be the child of a parent of a parent of parent of a parent, etc.). So at some point I will have to store an instance in a local variable - either the result of a queryset get or all. And at that point, I lose my connection to the parent item that I want to re-cache.

Any ideas?

(Note that I do not want to save the changes in a db yet.)

trubliphone
  • 4,132
  • 3
  • 42
  • 66
  • This is very confusing. Apart from anything else, you shouldn't think of the session as a cache. – Daniel Roseman Oct 07 '16 at 14:54
  • @DanielRoseman - I've made things a bit more standard. But caching isn't the issue. It's the fact that whenever I access "child" I am getting a new copy. – trubliphone Oct 07 '16 at 15:12
  • But I don't understand what else you would expect. You cache the parent; the child is a completely different item which you query separately from the database. – Daniel Roseman Oct 07 '16 at 15:22
  • @DanielRoseman - I want to change the child. And I want it so that whenever I access the child again those changes are there. – trubliphone Oct 07 '16 at 15:24
  • So why don't you cache the child? – Daniel Roseman Oct 07 '16 at 15:30
  • @DanielRoseman - b/c the child is only relevant in the context of the parent. The real code is dealing w/ a hierarchy of ~100 models at once; I might just be changing #23. – trubliphone Oct 07 '16 at 15:33
  • But I can't get past the fact that if you want the changes to the child to be cached, you need to store the child in the cache somehow. Currently you are not doing that, you're getting it separately from the db. – Daniel Roseman Oct 07 '16 at 15:35
  • Possible duplicate of [Why is Django returning stale cache data?](http://stackoverflow.com/questions/37849236/why-is-django-returning-stale-cache-data) – e4c5 Oct 07 '16 at 16:42
  • I believe my problem is occurring b/c Django *clones* querysets (to allow for chaining?) whenever I do things like `get` or `all` or `filter`. I think that the underlying call to `get_queryset` (from the manage?) does this. – trubliphone Oct 07 '16 at 17:13
  • It's not a good idea to cache entire Django model objects like this—there are too many internal things going on. A better idea would be to serialize your hierarchy to a list or dictionary, and put *that* in the cache. – csinchok Oct 07 '16 at 17:41
  • @PopcornArsonist - That is an excellent idea. It would be a lot of work to re-code things, but it's probably the best solution. – trubliphone Oct 08 '16 at 08:13

0 Answers0