Hi everyone,
Recently I have been tasked to investigate caching solutions for some of our queries at work and I think I found a roadblock that I am hoping someone here can shed some light at.
Consider this scenario:
I have two models: MyModelA and MyModelB.
class MyModelB(models.Model):
...
model_a = models.ForeignKey("MyModelA", models.CASCADE)
...
class MyModelA(models.Model):
...
Our system access MyModelA a lot, sometimes by itself (MyModelA.objects.get() (or filter())), sometimes via other models as in the MyModelB case. This obviously leads to thousands of calls that translate to SELECT * from MyModelA where id = X in the database.
My first instinct was to implement a CachedQuerySet class and override get so to cache MyModelA using the low-level cache api. So far, so good. The amount of calls to SELECT * from MyModelA where id = X was reduced, but it is still high.
I did a little digging and find out that accessing a child object of MyModelA will indeed also generate the SELECT calls. And guess what? There are a few places within my codebase where we do:
my_model_a = my_model_b.model_a
From here, I am not sure what would be the best way to go. I did think about a couple of options:
-
Should I write a method
get_model_ainside MyModelB which implements the same caching logic that I used for my CachedQuerySet? I know it would work BUT I would have to potentially write similar methods in other models. -
Should I try to override getattr? (It seems a bit too much tbh, as if I was forcing something into Django and Python)
Or, alternatively, has anyone here faced a similar problem and knows a better or more appropriate solution?
Thanks in advance,
Adriano