Skip to content

Commit

Permalink
wip: Try using localized_cached_property for cache_name
Browse files Browse the repository at this point in the history
  • Loading branch information
last-partizan committed Nov 9, 2024
1 parent 2ad3072 commit c55404b
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 27 deletions.
14 changes: 0 additions & 14 deletions modeltranslation/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,17 +482,3 @@ def __set__(self, instance, value):
loc_field_name = build_localized_fieldname(self.field_name, get_language())
loc_attname = instance._meta.get_field(loc_field_name).get_attname()
setattr(instance, loc_attname, value)


class LanguageCacheSingleObjectDescriptor:
"""
A Mixin for RelatedObjectDescriptors which use current language in cache lookups.
"""

accessor = None # needs to be set on instance

def get_cache_name(self) -> str:
"""
Used in django > 2.x
"""
return build_localized_fieldname(self.accessor, get_language()) # type: ignore[arg-type]
15 changes: 15 additions & 0 deletions modeltranslation/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from modeltranslation.utils import localized_cached_property, get_language
from django.utils.translation import override


def test_localized_cached_property():
class Foo:
@localized_cached_property
def bar(self):
return get_language()

instance = Foo()

for lang in ["en", "de"]:
with override(lang):
assert instance.bar == lang
33 changes: 21 additions & 12 deletions modeltranslation/translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from modeltranslation import settings as mt_settings
from modeltranslation.fields import (
NONE,
LanguageCacheSingleObjectDescriptor,
TranslatedManyToManyDescriptor,
TranslatedRelationIdDescriptor,
TranslationFieldDescriptor,
Expand All @@ -35,7 +34,12 @@
rewrite_lookup_key,
)
from modeltranslation.thread_context import auto_populate_mode
from modeltranslation.utils import build_localized_fieldname, parse_field
from modeltranslation.utils import (
build_localized_fieldname,
parse_field,
localized_cached_property,
get_language,
)

# Re-export the decorator for convenience
from modeltranslation.decorators import register
Expand Down Expand Up @@ -459,16 +463,21 @@ def patch_related_object_descriptor_caching(ro_descriptor):
language-aware caching.
"""

class NewSingleObjectDescriptor(LanguageCacheSingleObjectDescriptor, ro_descriptor.__class__):
pass

ro_descriptor.related.get_cache_name = partial(
NewSingleObjectDescriptor.get_cache_name,
ro_descriptor,
)

ro_descriptor.accessor = ro_descriptor.related.get_accessor_name()
ro_descriptor.__class__ = NewSingleObjectDescriptor
class NewRelated(ro_descriptor.related.__class__):
def get_cache_name(self) -> str:
"""
Used in django > 2.x
"""
return self.cache_name

@localized_cached_property
def cache_name(self):
"""
Used in django >= 5.1
"""
return build_localized_fieldname(self.get_accessor_name(), get_language())

ro_descriptor.related.__class__ = NewRelated


class Translator:
Expand Down
14 changes: 13 additions & 1 deletion modeltranslation/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from contextlib import contextmanager
from typing import Any, TypeVar
from collections.abc import Generator, Iterable, Iterator

from functools import cached_property
from django.db import models
from django.utils.encoding import force_str
from django.utils.functional import lazy
Expand Down Expand Up @@ -248,3 +248,15 @@ def lazy_register_model(old_model, new_model, translator):
translator.lazy_operation(lazy_register_model, intermediary_model, klass)

return klass


class localized_cached_property(cached_property):
_attrname: str | None = None

@property
def attrname(self) -> str | None:
return self._attrname and "-".join((self._attrname, get_language()))

@attrname.setter
def attrname(self, value: str | None):
self._attrname = value

0 comments on commit c55404b

Please sign in to comment.