models.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. # -*- coding: utf-8 -*-
  2. """
  3. flaskbb.management.models
  4. ~~~~~~~~~~~~~~~~~~~~~~~~~
  5. This module contains all management related models.
  6. :copyright: (c) 2014 by the FlaskBB Team.
  7. :license: BSD, see LICENSE for more details.
  8. """
  9. from flaskbb._compat import iteritems
  10. from flaskbb.extensions import db, cache
  11. from flaskbb.utils.database import CRUDMixin
  12. from flaskbb.utils.forms import generate_settings_form, SettingValueType
  13. class SettingsGroup(db.Model, CRUDMixin):
  14. __tablename__ = "settingsgroup"
  15. key = db.Column(db.String(255), primary_key=True)
  16. name = db.Column(db.String(255), nullable=False)
  17. description = db.Column(db.Text, nullable=False)
  18. settings = db.relationship("Setting", lazy="dynamic", backref="group",
  19. cascade="all, delete-orphan")
  20. def __repr__(self):
  21. return "<{} {}>".format(self.__class__.__name__, self.key)
  22. class Setting(db.Model, CRUDMixin):
  23. __tablename__ = "settings"
  24. key = db.Column(db.String(255), primary_key=True)
  25. value = db.Column(db.PickleType, nullable=False)
  26. settingsgroup = db.Column(db.String(255),
  27. db.ForeignKey('settingsgroup.key',
  28. use_alter=True,
  29. name="fk_settingsgroup"),
  30. nullable=False)
  31. # The name (displayed in the form)
  32. name = db.Column(db.String(200), nullable=False)
  33. # The description (displayed in the form)
  34. description = db.Column(db.Text, nullable=False)
  35. # Available types: string, integer, float, boolean, select, selectmultiple
  36. value_type = db.Column(db.Enum(SettingValueType), nullable=False)
  37. # Extra attributes like, validation things (min, max length...)
  38. # For Select*Fields required: choices
  39. extra = db.Column(db.PickleType)
  40. @classmethod
  41. def get_form(cls, group):
  42. """Returns a Form for all settings found in :class:`SettingsGroup`.
  43. :param group: The settingsgroup name. It is used to get the settings
  44. which are in the specified group.
  45. """
  46. return generate_settings_form(settings=group.settings)
  47. @classmethod
  48. def get_all(cls):
  49. return cls.query.all()
  50. @classmethod
  51. def update(cls, settings, app=None):
  52. """Updates the cache and stores the changes in the
  53. database.
  54. :param settings: A dictionary with setting items.
  55. """
  56. # update the database
  57. for key, value in iteritems(settings):
  58. setting = cls.query.filter(Setting.key == key.lower()).first()
  59. setting.value = value
  60. db.session.add(setting)
  61. db.session.commit()
  62. cls.invalidate_cache()
  63. @classmethod
  64. def get_settings(cls, from_group=None):
  65. """This will return all settings with the key as the key for the dict
  66. and the values are packed again in a dict which contains
  67. the remaining attributes.
  68. :param from_group: Optionally - Returns only the settings from a group.
  69. """
  70. result = None
  71. if from_group is not None:
  72. result = from_group.settings
  73. else:
  74. result = cls.query.all()
  75. settings = {}
  76. for setting in result:
  77. settings[setting.key] = setting.value
  78. return settings
  79. @classmethod
  80. @cache.cached(key_prefix="settings")
  81. def as_dict(cls, from_group=None, upper=True):
  82. """Returns all settings as a dict. This method is cached. If you want
  83. to invalidate the cache, simply execute ``self.invalidate_cache()``.
  84. :param from_group: Returns only the settings from the group as a dict.
  85. :param upper: If upper is ``True``, the key will use upper-case
  86. letters. Defaults to ``False``.
  87. """
  88. settings = {}
  89. result = None
  90. if from_group is not None:
  91. result = SettingsGroup.query.filter_by(key=from_group).\
  92. first_or_404()
  93. result = result.settings
  94. else:
  95. result = cls.query.all()
  96. for setting in result:
  97. if upper:
  98. setting_key = setting.key.upper()
  99. else:
  100. setting_key = setting.key
  101. settings[setting_key] = setting.value
  102. return settings
  103. @classmethod
  104. def invalidate_cache(cls):
  105. """Invalidates this objects cached metadata."""
  106. cache.delete_memoized(cls.as_dict, cls)