Simple app to add configuration options to a Django project.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 127 lines 4.2 kB view raw
1from typing import TYPE_CHECKING, Optional, Sequence, Union 2 3from django.core.cache import caches 4from django.db import models 5 6from options import get_option_model 7from options.settings import ( 8 DEFAULT_EXCLUDE_USER, 9 DEFAULT_OPTION_CACHE_ALIAS, 10 DEFAULT_OPTION_CACHE_TIMEOUT, 11) 12 13if TYPE_CHECKING: 14 from django.contrib.auth.models import User 15 16 17class OptionQuerySet(models.QuerySet): 18 def public(self) -> "OptionQuerySet": 19 """Gets public options.""" 20 return self.filter(is_public=True) 21 22 23class OptionManager(models.Manager): 24 """Manager for options.""" 25 26 cache_prefix = "_options_option_" 27 28 def __get_cached_value( 29 self, name: str 30 ) -> Optional[Union[int, float, str, Sequence]]: 31 return caches[DEFAULT_OPTION_CACHE_ALIAS].get(f"{self.cache_prefix}{name}") 32 33 def __set_cached_value( 34 self, name: str, value: Union[int, float, str, Sequence] 35 ) -> None: 36 caches[DEFAULT_OPTION_CACHE_ALIAS].set( 37 f"{self.cache_prefix}{name}", value, DEFAULT_OPTION_CACHE_TIMEOUT 38 ) 39 40 def get_queryset(self) -> "OptionQuerySet": 41 return OptionQuerySet(self.model, using=self._db) 42 43 def public(self) -> "OptionQuerySet": 44 """Gets public options.""" 45 return self.get_queryset().public() 46 47 def get_value( 48 self, name: str, default: Optional[Union[int, float, str, Sequence]] = None 49 ) -> Optional[Union[int, float, str, Sequence]]: 50 """Gets the value with the proper type.""" 51 _cached_value = self.__get_cached_value(name=name) 52 if _cached_value is not None: 53 return _cached_value 54 try: 55 option = self.model.objects.get(name=name) 56 value = option.get_value() 57 except self.model.DoesNotExist: 58 value = default 59 self.__set_cached_value(name=name, value=value) 60 return value 61 62 63class UserOptionQuerySet(models.QuerySet): 64 def public(self) -> "UserOptionQuerySet": 65 """Gets public options.""" 66 return self.filter(is_public=True) 67 68 69class UserOptionManager(models.Manager): 70 """Manager to handle user's custom options.""" 71 72 cache_prefix = "_option_user_option_" 73 74 def __get_cached_value( 75 self, name: str, user: Optional["User"] = None 76 ) -> Optional[Union[int, float, str, Sequence]]: 77 key = ( 78 f"{self.cache_prefix}{name}" 79 if user is None 80 else f"{self.cache_prefix}{name}_{user.pk}" 81 ) 82 return caches[DEFAULT_OPTION_CACHE_ALIAS].get(key) 83 84 def __set_cached_value( 85 self, 86 name: str, 87 value: Union[int, float, str, Sequence], 88 user: Optional["User"] = None, 89 ) -> None: 90 key = ( 91 f"{self.cache_prefix}{name}" 92 if user is None 93 else f"{self.cache_prefix}{name}_{user.pk}" 94 ) 95 caches[DEFAULT_OPTION_CACHE_ALIAS].set(key, value, DEFAULT_OPTION_CACHE_TIMEOUT) 96 97 def get_queryset(self) -> "UserOptionQuerySet": 98 return OptionQuerySet(self.model, using=self._db) 99 100 def public(self) -> "UserOptionQuerySet": 101 """Gets public options.""" 102 return self.get_queryset().public() 103 104 def filter_user_customizable(self) -> "UserOptionQuerySet": 105 """Returns option that the user can customize himself.""" 106 return self.exclude(name__in=DEFAULT_EXCLUDE_USER) 107 108 def get_value( 109 self, 110 name, 111 user: Optional["User"] = None, 112 default: Optional[Union[int, float, str, Sequence]] = None, 113 ) -> Optional[Union[int, float, str, Sequence]]: 114 """Gets the value with the proper type.""" 115 Option = get_option_model() 116 _cached_value = self.__get_cached_value(name=name, user=user) 117 if _cached_value is not None: 118 return _cached_value 119 if user is None: 120 value = Option.objects.get_value(name=name, default=default) 121 try: 122 option = self.model.objects.get(user=user, name=name) 123 value = option.get_value() 124 except self.model.DoesNotExist: 125 value = Option.objects.get_value(name=name, default=default) 126 self.__set_cached_value(name=name, value=value, user=user) 127 return value