[Django]-Cached_property and classmethod doesnt work together, Django

5πŸ‘

βœ…

For cached property with classmethod usage i wrote that code a few days ago:

from django.utils.decorators import classproperty

class cached_classproperty(classproperty):
    def get_result_field_name(self):
        return self.fget.__name__ + "_property_result" if self.fget else None

    def __get__(self, instance, cls=None):
        result_field_name = self.get_result_field_name()

        if hasattr(cls, result_field_name):
            return getattr(cls, result_field_name)

        if not cls or not result_field_name:
            return self.fget(cls)

        setattr(cls, result_field_name, self.fget(cls))
        return getattr(cls, result_field_name)

It will be caching result in class-level.
Usage is similar as classproperty:

@cached_classproperty
def some_func(cls, *args, **kwargs):
    ...

If you do not have django in dependencies, then you may want prevent classproperty parent usage (sources). In that case you may use that decorator:

class cached_classproperty(classproperty):
    def __init__(self, method=None):
        self.fget = method

    def get_result_field_name(self):
        return self.fget.__name__ + "_property_result" if self.fget else None

    def __get__(self, instance, cls=None):
        result_field_name = self.get_result_field_name()

        if hasattr(cls, result_field_name):
            return getattr(cls, result_field_name)

        if not cls or not result_field_name:
            return self.fget(cls)

        setattr(cls, result_field_name, self.fget(cls))
        return getattr(cls, result_field_name)

    def getter(self, method):
        self.fget = method
        return self
πŸ‘€ncopiy

Leave a comment