Closed danmash closed 1 year ago
This means cacheops was not installed for this model. Which probably means models queryset does not descend from django.db.models.QuerySet
. Is it so?
it was some import problem. I had to move the import statement of a function which uses @cached_as
to the method where it's called.
It's weird that you get such error though. Maybe you need cacheops moved upper in apps list.
I got this error by using @cached_as
in the models.py
file just under the model definition.
I had to move it outside the model itself. I can't use @cached_as(MyModel)
on any of MyModel
methods since MyModel
is not defined yet. I would like @cached_as
to accept model name or 'self'
.
Currently cacheops installs its monkey patches after all models are collected, e.g. app registry is ready, along with other installation tweaks, like setting up signal handlers. Thus the error. Signals cannot be connected before models are ready, so one will need to split cacheops installation process into two phases to make @cached_as()
work in models.py
.
The above assumes @caches_as()
stays the same, i.e. it precalculates some stuff at the decorator call time, so that won't need to do that on every func call. However, if one wants to use lazily defined samples like in your examples then @cached_as()
needs to be changed anyway.
I thought of adding something like:
@cached_as(lambda category_id: Model.objects.filter(category_id=category_id))
def some_func(category_id):
...
which will also require adjusting @cached_as()
in a similar way.
The main thing that stopped me from doing that is that you can always create a subfunction and wrap that one:
def some_func(category_id):
qs = Model.objects.filter(category_id=category_id)
@cached_as(qs)
def _some_func():
... # can use `qs` here
return _some_func()
This could be put into models.py
and will also work with methods:
class MyModel(models.Model):
def some_method(self):
@cached_as(self)
def _some_method():
...
return _some_method()
It may look awkward but unlike special string syntax it does not constrain you in any way. Also, you way reuse a queryset both in @cached_as()
and inside a cached function.
It is possible to implement simple cases like refering to the model or self
, which are different things BTW:
@cached_as(obj)
def foo():
...
# is the same as
@cached_as(obj.__class__.objects.filter(pk=obj.pk))
def foo():
...
I wonder if this will promote people of not using more granular querset in @cached_as()
though. Or obscure more complex scenarios covered by a nested function.
Maybe you can tell more about your use cases.
Closing this with a nested function as the blessed approach for now.
I have an error when trying to use
@cached_as(OmittedLeadEmail)