108 lines
2.7 KiB
Python
108 lines
2.7 KiB
Python
import json
|
|
|
|
from django import forms
|
|
from django.conf import settings
|
|
from django.contrib.postgres.forms import JSONField
|
|
from dynamic_preferences import serializers, types
|
|
from dynamic_preferences.registries import global_preferences_registry
|
|
|
|
|
|
class DefaultFromSettingMixin:
|
|
def get_default(self):
|
|
return getattr(settings, self.setting)
|
|
|
|
|
|
def get(pref):
|
|
manager = global_preferences_registry.manager()
|
|
return manager[pref]
|
|
|
|
|
|
def all():
|
|
manager = global_preferences_registry.manager()
|
|
return manager.all()
|
|
|
|
|
|
def set(pref, value):
|
|
manager = global_preferences_registry.manager()
|
|
manager[pref] = value
|
|
|
|
|
|
class StringListSerializer(serializers.BaseSerializer):
|
|
separator = ","
|
|
sort = True
|
|
|
|
@classmethod
|
|
def to_db(cls, value, **kwargs):
|
|
if not value:
|
|
return
|
|
|
|
if type(value) not in [list, tuple]:
|
|
raise cls.exception(
|
|
f"Cannot serialize, value {value} is not a list or a tuple"
|
|
)
|
|
|
|
if cls.sort:
|
|
value = sorted(value)
|
|
return cls.separator.join(value)
|
|
|
|
@classmethod
|
|
def to_python(cls, value, **kwargs):
|
|
if not value:
|
|
return []
|
|
return value.split(",")
|
|
|
|
|
|
class StringListPreference(types.BasePreferenceType):
|
|
serializer = StringListSerializer
|
|
field_class = forms.MultipleChoiceField
|
|
|
|
def get_api_additional_data(self):
|
|
d = super().get_api_additional_data()
|
|
d["choices"] = self.get("choices")
|
|
return d
|
|
|
|
|
|
class JSONSerializer(serializers.BaseSerializer):
|
|
required = True
|
|
|
|
@classmethod
|
|
def to_db(cls, value, **kwargs):
|
|
if not cls.required and value is None:
|
|
return json.dumps(value)
|
|
data_serializer = cls.data_serializer_class(data=value)
|
|
if not data_serializer.is_valid():
|
|
raise cls.exception(
|
|
f"{value} is not a valid value: {data_serializer.errors}"
|
|
)
|
|
value = data_serializer.validated_data
|
|
try:
|
|
return json.dumps(value, sort_keys=True)
|
|
except TypeError:
|
|
raise cls.exception(
|
|
f"Cannot serialize, value {value} is not JSON serializable"
|
|
)
|
|
|
|
@classmethod
|
|
def to_python(cls, value, **kwargs):
|
|
return json.loads(value)
|
|
|
|
|
|
class SerializedPreference(types.BasePreferenceType):
|
|
"""
|
|
A preference that store arbitrary JSON and validate it using a rest_framework
|
|
serializer
|
|
"""
|
|
|
|
serializer = JSONSerializer
|
|
data_serializer_class = None
|
|
field_class = JSONField
|
|
widget = forms.Textarea
|
|
|
|
@property
|
|
def serializer(self):
|
|
class _internal(JSONSerializer):
|
|
data_serializer_class = self.data_serializer_class
|
|
required = self.get("required")
|
|
|
|
return _internal
|