-
Notifications
You must be signed in to change notification settings - Fork 111
/
conf.py
151 lines (112 loc) · 5.04 KB
/
conf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import inspect
from django.conf import settings as django_settings
from django.test.signals import setting_changed
DYNAMIC_REST = {
# DEBUG: enable/disable internal debugging
'DEBUG': False,
# ENABLE_BROWSABLE_API: enable/disable the browsable API.
# It can be useful to disable it in production.
'ENABLE_BROWSABLE_API': True,
# ENABLE_LINKS: enable/disable relationship links
'ENABLE_LINKS': True,
# ENABLE_SERIALIZER_CACHE: enable/disable caching of related serializers
'ENABLE_SERIALIZER_CACHE': True,
# ENABLE_SERIALIZER_OBJECT_CACHE: enable/disable caching of serialized
# objects within a serializer instance/context. This can yield
# significant performance improvements in cases where the same objects
# are sideloaded repeatedly.
'ENABLE_SERIALIZER_OBJECT_CACHE': True,
# ENABLE_SERIALIZER_OPTIMIZATIONS: enable/disable representation speedups
'ENABLE_SERIALIZER_OPTIMIZATIONS': True,
# ENABLE_BULK_PARTIAL_CREATION: enable/disable partial creation in bulk
'ENABLE_BULK_PARTIAL_CREATION': False,
# ENABLE_BULK_UPDATE: enable/disable update in bulk
'ENABLE_BULK_UPDATE': True,
# ENABLE_PATCH_ALL: enable/disable patch by queryset
'ENABLE_PATCH_ALL': False,
# DEFER_MANY_RELATIONS: automatically defer many-relations, unless
# `deferred=False` is explicitly set on the field.
'DEFER_MANY_RELATIONS': False,
# LIST_SERIALIZER_CLASS: Globally override the list serializer class.
# Default is `DynamicListSerializer` and also can be overridden for
# each serializer class by setting `Meta.list_serializer_class`.
'LIST_SERIALIZER_CLASS': None,
# MAX_PAGE_SIZE: global setting for max page size.
# Can be overriden at the viewset level.
'MAX_PAGE_SIZE': None,
# PAGE_QUERY_PARAM: global setting for the pagination query parameter.
# Can be overriden at the viewset level.
'PAGE_QUERY_PARAM': 'page',
# PAGE_SIZE: global setting for page size.
# Can be overriden at the viewset level.
'PAGE_SIZE': None,
# PAGE_SIZE_QUERY_PARAM: global setting for the page size query parameter.
# Can be overriden at the viewset level.
'PAGE_SIZE_QUERY_PARAM': 'per_page',
# EXCLUDE_COUNT_QUERY_PARAM: global setting for the query parameter
# that disables counting during PageNumber pagination
'EXCLUDE_COUNT_QUERY_PARAM': 'exclude_count',
# ADDITIONAL_PRIMARY_RESOURCE_PREFIX: String to prefix additional
# instances of the primary resource when sideloading.
'ADDITIONAL_PRIMARY_RESOURCE_PREFIX': '+',
# Enables host-relative links. Only compatible with resources registered
# through the dynamic router. If a resource doesn't have a canonical
# path registered, links will default back to being resource-relative urls
'ENABLE_HOST_RELATIVE_LINKS': True,
# Enables caching of serializer fields to speed up serializer usage
# Needs to also be configured on a per-serializer basis
'ENABLE_FIELDS_CACHE': False,
# Enables use of hashid fields
'ENABLE_HASHID_FIELDS': False,
# Salt value to salt hash ids.
# Needs to be non-nullable if 'ENABLE_HASHID_FIELDS' is set to True
'HASHIDS_SALT': None,
}
# Attributes where the value should be a class (or path to a class)
CLASS_ATTRS = [
'LIST_SERIALIZER_CLASS',
]
class Settings(object):
def __init__(self, name, defaults, settings, class_attrs=None):
self.name = name
self.defaults = defaults
self.keys = set(defaults.keys())
self.class_attrs = class_attrs
self._cache = {}
self._reload(getattr(settings, self.name, {}))
setting_changed.connect(self._settings_changed)
def _reload(self, value):
"""Reload settings after a change."""
self.settings = value
self._cache = {}
def _load_class(self, attr, val):
if inspect.isclass(val):
return val
elif isinstance(val, str):
parts = val.split('.')
module_path = '.'.join(parts[:-1])
class_name = parts[-1]
mod = __import__(module_path, fromlist=[class_name])
return getattr(mod, class_name)
elif val:
raise Exception("%s must be string or a class" % attr)
def __getattr__(self, attr):
"""Get a setting."""
if attr not in self._cache:
if attr not in self.keys:
raise AttributeError("Invalid API setting: '%s'" % attr)
if attr in self.settings:
val = self.settings[attr]
else:
val = self.defaults[attr]
if attr in self.class_attrs and val:
val = self._load_class(attr, val)
# Cache the result
self._cache[attr] = val
return self._cache[attr]
def _settings_changed(self, *args, **kwargs):
"""Handle changes to core settings."""
setting, value = kwargs['setting'], kwargs['value']
if setting == self.name:
self._reload(value)
settings = Settings('DYNAMIC_REST', DYNAMIC_REST, django_settings, CLASS_ATTRS)