···11# -*- coding: utf-8 -*-
22-from __future__ import unicode_literals, print_function, division, absolute_import
33-42import logging
53import six
64from django.apps import AppConfig
···1513def create_default_options(sender, **kwargs):
1614 """Creates the defaults configuration options if they don't exists."""
1715 from options.models import Option
1616+1817 for key, data in six.iteritems(DEFAULT_OPTIONS):
1918 if not Option.objects.filter(name=key).exists():
2019 try:
···11# -*- coding: utf-8 -*-
22-from __future__ import unicode_literals, print_function, division, absolute_import
22+3344import six
55-from django.contrib.gis.db import models
66-from django.utils.encoding import python_2_unicode_compatible
55+from django.conf import settings
66+from django.db import models
77from django.utils.translation import ugettext_lazy as _
8899from options import STRING, TYPE_CHOICES, INT, FLOAT
1010-from options.managers import OptionManager
1010+from options.managers import OptionManager, UserOptionManager
111112121313-@python_2_unicode_compatible
1414-class Option(models.Model):
1515- """System options and configurations."""
1313+class BaseOption(models.Model):
1414+ """Base model for system options and configurations."""
16151716 name = models.CharField(
1818- verbose_name=_("Parameter"),
1919- max_length=255,
2020- unique=True,
2121- db_index=True
1717+ verbose_name=_("Parameter"), max_length=255, unique=True, db_index=True
2218 )
2319 public_name = models.CharField(
2420 verbose_name=_("Public name of the parameter"),
2521 max_length=255,
2622 unique=False,
2727- db_index=True
2828- )
2929- type = models.PositiveIntegerField(
3030- choices=TYPE_CHOICES,
3131- default=STRING
2323+ db_index=True,
3224 )
2525+ type = models.PositiveIntegerField(choices=TYPE_CHOICES, default=STRING)
3326 value = models.CharField(
3434- null=True,
3535- blank=True,
3636- default=None,
3737- max_length=256,
3838- verbose_name=_("Value")
2727+ null=True, blank=True, default=None, max_length=256, verbose_name=_("Value")
3928 )
4040-4129 is_list = models.BooleanField(default=False)
42304343- objects = OptionManager()
3131+ class Meta:
3232+ abstract = True
44334534 def __str__(self):
4635 return "%s" % self.public_name
47363737+ def _convert_value(self, value, type):
3838+ converter = {INT: int, FLOAT: float, STRING: six.text_type}
3939+ default_values = {INT: 0, FLOAT: 1.0, STRING: ""}
4040+ try:
4141+ option_value = converter.get(self.type, six.text_type)(self.value)
4242+ except ValueError:
4343+ option_value = default_values.get(self.type)
4444+ return option_value
4545+4846 def get_value(self):
4949- """Gets the value with the proper type."""
5050- converter = {
5151- INT: int,
5252- FLOAT: float,
5353- STRING: six.text_type
5454- }
4747+ """Gets the value with the proper type. If the type is not
4848+ valid it would return the default value for the field, to avoid
4949+ problems with manual database modifications"""
5050+5551 if not self.is_list:
5656- return converter.get(self.type, six.text_type)(self.value)
5252+ return self._convert_value(self.value, self.type)
5753 else:
5854 values = self.value.split(",")
5959- return list(map(lambda item: converter.get(self.type, six.text_type)(item), values))
5555+ return [self._convert_value(self.type, item) for item in values]
5656+5757+ def clean(self):
5858+ from django.core.exceptions import ValidationError
5959+6060+ converter = {INT: int, FLOAT: float, STRING: six.text_type}
6161+ try:
6262+ converter.get(self.type, six.text_type)(self.value)
6363+ except ValueError:
6464+ raise ValidationError(_("Invalid value for this type."))
6565+6666+ def save(self, *args, **kwargs):
6767+ self.clean()
6868+ super().save(*args, **kwargs)
6969+7070+7171+class Option(BaseOption):
7272+ """System options and configurations."""
7373+7474+ objects = OptionManager()
7575+7676+ class Meta:
7777+ ordering = ["public_name"]
7878+7979+8080+class UserOption(BaseOption):
8181+ """Custom option for a user."""
8282+8383+ user = models.ForeignKey(
8484+ settings.AUTH_USER_MODEL, related_name="options", on_delete=models.CASCADE
8585+ )
8686+ name = models.CharField(verbose_name=_("Parameter"), max_length=255)
8787+8888+ objects = UserOptionManager()
8989+9090+ class Meta:
9191+ unique_together = ["user", "name"]
9292+ ordering = ["public_name"]
+3
options/settings.py
···1717# }
1818#
1919DEFAULT_OPTIONS = getattr(settings, "CONFIGURATION_DEFAULT_OPTIONS", {})
2020+2121+# Set the list of options that the user can't customize.
2222+DEFAULT_EXCLUDE_USER_OPTIONS = getattr(settings, "EXCLUDE_USER_OPTIONS", tuple())