"""
Abstract
--------
There are a large number of settings which control SuperDjango's behavior. A means of centralizing and documenting these
was desired.
.. note::
Regarding the choice of django-appconf: Prior to SuperDjango 4, various approaches were used and all suffered from
one problem or another. The django-appconf app rather nicely meets the need of centralizing settings, and (as of
this writing) has 100% code coverage. However, should it need to be replaced, the source code is relatively
straight-forward, and could be adapted and modernized if need be.
"""
__author__ = "Shawn Davis <shawn@superdjango.com>"
__maintainer__ = "Shawn Davis <shawn@superdjango.com>"
__version__ = "4.1.1-d"
# Imports
from appconf import AppConf
from django.conf import settings
import os
# Classes
[docs]class General(AppConf):
"""General settings used by SuperDjango.
To override or set the value of a general setting, add it to your ``settings.py`` file with the ``SUPERDJANGO_``
prefix. For example:
.. code-block:: python
SUPERDJANGO_BASE_TEMPLATE = "base_site.html"
"""
AJAX_MODULE_NAME = "ajax"
"""The name of the module (or package) that contains code for automated integration of AJAX views."""
API_MODULE_NAME = "api"
"""The name of the module (or package) that contains code for automated Django REST Framework integration."""
BASE_TEMPLATE = "base.html"
"""The base template to extend."""
DATA_PATH = None
"""The path to data stored for the project or its apps."""
DATE_MASK = "%b %d, %Y"
"""The default `strftime() <https://docs.python.org/3.7/library/datetime.html#strftime-strptime-behavior>_`
specification which should be used to format dates.
"""
DATETIME_MASK = "%b %d, %Y %I:%M%p"
"""The default `strftime() <https://docs.python.org/3.7/library/datetime.html#strftime-strptime-behavior>_`
specification which should be used to format datetime objects.
"""
FORM_DEBUG = False
"""Indicates form debugging is enabled. Note: This must be included in the context; see
``superdjango.context_processors.settings_in_context``.
"""
HELP_ENABLED = "superdjango.contrib.support.apps.DefaultConfig" in settings.INSTALLED_APPS
"""Used internally in SuperDjango UI templates. Indicates whether the support application is enabled."""
MARKDOWN_EXTENSIONS = ["extra"]
"""The extensions to be enabled when working with Markdown content.
See https://python-markdown.github.io/extensions/extra/
"""
PAGINATION_LIMIT = 10
"""The default number of records to show in a list view."""
REDIRECT_KEY = "next"
"""The name of the GET key used to send a user to a URL after logging in."""
SCHEDULER_MODULE_NAME = "scheduler"
"""The module name for apps wishing to contribute jobs to ``superdjango.contrib.scheduler``."""
SCHEDULER_PATH = os.path.join(settings.BASE_DIR, "../config", "scheduler.ini")
"""The path to the scheduled jobs configuration."""
SSL_REQUIRED = not settings.DEBUG
"""Indicates whether UI views must be served via a secure connection. By default, SSL is required except for
development.
"""
UPPERS = [
"api",
"cname",
"css",
"hr",
"html",
"id",
"imap",
"inc",
"llc",
"pop3",
"purl",
"rss",
"sla",
"sms",
"smtp",
"ssl",
"tcp",
"tls",
"url",
"vip",
"xml",
]
"""The default list of strings to be converted to upper case by SuperDjango's ``title()`` shortcut."""
USE_CDN = not settings.DEBUG
"""Indicates that SuperDjango's CDN should be used for static files, when available. The default is to use bundled
files when ``DEBUG`` is ``True`` and the preferred CDN of the resource when ``DEBUG`` is ``False.``
"""
WEBMASTER_EMAIL = "webmaster@superdjango.com"
"""The email address from which site email will be sent."""
WEBMASTER_NAME = "Webmaster"
"""The name of the site's webmaster."""
class Meta:
prefix = "superdjango"
[docs]class Internationalization(AppConf):
COUNTRY_CHOICES = None
"""A choice list of ISO-3166-1 codes and country names."""
DEFAULT_COUNTRY_CODE = None
"""The default country code to use for ``CountryField``."""
DEFAULT_CURRENCY_CODE = None
"""The default currency code to use for ``CurrencyField``."""
TIMEZONE_CHOICES = None
"""A list of choices for time zone form fields."""
TIMEZONE_KEY = "django_time_zone"
"""The name of the session key used to store the user's time zone."""
class Meta:
prefix = "superdjango_i18n"
[docs]class Support(AppConf):
"""Configuration for ``contrib.support``."""
MARKDOWN_EXTENSIONS = ["extra"]
"""A list of Markdown extensions to use when rendering support docs."""
PATH = os.path.join(settings.BASE_DIR, "../help")
"""The path to support content."""
REQUIRES_LOGIN = True
"""Indicates whether accessing support content requires an authenticated users."""
SEARCH_LOG_RESULTS = True
"""Indicates search results should be logged. Helps improve the search catalog."""
SEARCH_TERMS = list()
"""A list of terms that may be used to build the search catalog."""
URL = "/help/"
"""The URL where support content may be accessed."""
class Meta:
prefix = "superdjango_support"
[docs]class User(AppConf):
"""User-related settings provided by SuperDjango."""
AUTO_CREATE_PROFILE = False
"""Indicates that a user profile instance should be created, if possible, when one does not already exist. Consider
setting this to ``False`` while setting ``auto_create`` to ``True`` on your ``ProfileUpdate`` view. See profile
views for an example.
"""
LOGIN_EXCLUDED_URLS = None
"""Include URLs that do not (or should not) require a log in when ``LoginRequiredMiddleware`` is enabled. Django's
``LOGIN_URL`` is added automatically.
"""
LOGIN_REDIRECT_URL = settings.LOGIN_REDIRECT_URL
"""The URL to which users are redirected (by default) after a successful login."""
LOGIN_REQUIRED = True
"""Indicates that an authenticated user is the default for accessing views."""
LOGOUT_REDIRECT_URL = "/"
"""The URL to which users are redirected after logging out."""
MAX_LOGIN_ATTEMPTS = None
"""The maximum number of login attempts (int) before a user account is locked."""
MAX_LOGIN_MINUTES = None
"""The number of minutes (int) between max login attempts."""
MAX_PASSWORD_RESET_ATTEMPTS = 3
"""The maximum number of password reset attempts (int) before a user account is locked."""
MAX_PASSWORD_RESET_MINUTES = 30
"""The number of minutes (int) between max password reset attempts."""
ORDER_USERS_BY = "first_name"
"""The field name by which to order user lists."""
PASSWORD_RESET_LOGIN = False
"""Indicates whether the user should be logged in after a password reset has been confirmed."""
PASSWORD_RESET_LOGGING_ENABLED = False
"""Indicates logging should be enabled for password reset attempts. Requires ``PASSWORD_RESET_MODEL``."""
PASSWORD_RESET_MODEL = None
"""The model used for logging password reset attempts in ``app_label.ModelName`` format."""
PASSWORD_RESET_USERNAME_ENABLED = False
"""When ``True``, the reset lookup will also attempt to find a given user name if one has been given."""
REDIRECT_TO_CHOICES = None
"""A list of Django choices used for the ``redirect_to`` dropdown of the ``ProfileModel``."""
REMEMBER_ME_ENABLED = False
"""Indicates whether "remember me" is presented on the login form."""
REMEMBER_ME_SECONDS = 30 * 24 * 60 * 60
"""The number of seconds (int) a user's session should last when the remember me option is selected. Defaults to 30
days.
"""
SSO_SERVICE_URL = None
"""This is the service URL sent to the provider. The provider may need to be configured to accept this URL. When
``DEBUG`` is ``True``, it defaults to the development URL. Otherwise an ``ImproperlyConfigured`` is raised if this
value is not defined.
"""
SSO_LINK_USER = False
"""When using the ``multisso`` app, this provides the option of connecting the user account with the record of the
SSO provider.
"""
IMPERSONATION_ENABLED_FOR_GROUPS = None
"""Indicates user impersonation is available to users belonging to any of the group names in the list."""
IMPERSONATION_ENABLED_FOR_STAFF = True
"""Indicates user impersonation is available to ``is_staff`` users."""
IMPERSONATION_MODEL = None
"""The model used to log impersonation history."""
INVITATION_EXPIRATION = 10 * 24 * 60 * 60
"""The number of days before a user invitation expires."""
INVITATION_LIMIT = None
"""The number of invitations that a user may send."""
INVITATION_MODEL = None
"""The model to use for user invitations."""
INVITATIONS_ENABLED = False
"""Indicates whether users are allowed to invite other users."""
INVITATION_GROUPS = None
"""A list of groups (names) into which a user will be placed upon accepting an invitation."""
PROFILE_MODEL = None
"""The model used for user profile in ``app_label.ModelName`` format."""
REGISTRATION_AFTER_URL = None
"""The URL to which a visitor will be directed after submitting a registration request.has been created. The default
is the ``RegistrationSubmitted`` view.
"""
REGISTRATION_ALLOWED_DOMAINS = None
"""A list of the email domains that are recognized (allowed) for self-registration."""
REGISTRATION_APPROVAL_HOURS = 48
"""The average number of hours (int) needed to manually approve registrations when approval is required. This may be
displayed to users after sign-up.
"""
REGISTRATION_APPROVAL_REQUIRED = False
"""Indicates whether new registrations require admin approval."""
REGISTRATION_AUTO_LOGIN = True
"""Indicates a user should be logged in upon a successful (completed) registration."""
REGISTRATION_BEFORE_URL = None
"""The URL to which a visitor will be directed before a registration may be requested. For example, this could be
used to direct the user to a Terms and Conditions page. The page should include a link to the ``RegistrationCreate``
view that includes ``reg=1`` in the URL.
"""
REGISTRATION_BODY = None
"""The body of the email message sent to visitors upon new user account registration. If omitted, the standard
template is used.
"""
REGISTRATION_CONFIRMATION_BODY = None
"""The body of the email message sent to visitors upon new user account registration. If omitted, the standard
template is used.
"""
REGISTRATION_CONFIRMATION_REQUIRED = True
"""Indicates whether new user registrations require user confirmation. This invokes the Confirmation Workflow."""
REGISTRATION_CONFIRMATION_SUBJECT_LINE = None
"""The subject line of the email message sent to visitors upon new user account registration. If omitted, the
standard template is used.
"""
REGISTRATION_DECLINED_BODY = None
"""The body of the email message sent when a registration is declined. ``REGISTRATION_APPROVAL_REQUIRED`` must
be ``True``. If omitted, the default template is used.
"""
REGISTRATION_DECLINED_SUBJECT = None
"""the subject line of the declined registration email. If omitted, the default template is used."""
REGISTRATION_DISABLED_MESSAGE =None
"""The message to display when registration is currently disabled."""
REGISTRATION_DISABLED_URL = "/"
"""The URL to which a visitor will be directed upon attempting to register an account when registration is
currently disabled. This defaults to the ``RegistrationDisabled`` view if enabled.
"""
REGISTRATION_ENABLED = False
"""Allows visitors to sign up for user accounts."""
REGISTRATION_EXPIRES_AFTER_DAYS = 7
"""The number of days (int) a registration remains valid after it is sent."""
REGISTRATION_FORM = None
"""The form to use for user registrations."""
REGISTRATION_GROUPS = None
"""A list of group names to which the user should be assigned upon successful (completed) registration."""
REGISTRATION_MODEL = None
"""The model (in the form of ``app_label.ModelName``) to use when registration approvals are required."""
REGISTRATION_OPEN_DATE = None
"""The date upon which user registration will again be allowed."""
REGISTRATION_OPEN_URL = None
"""The URL where a user may be notified (or request notification) when registration is available. This might be a
page or a sign-up form.
"""
REGISTRATION_REDIRECT_URL = None
"""the URL to which a new user will directed after confirming a registration. The default is the
``RegistrationComplete`` view."""
REGISTRATION_SALT = "registration"
"""The salt to use for creating activation keys."""
REGISTRATION_SUBJECT_LINE = None
"""The subject line of the email message sent to visitors upon new user account registration. If omitted, the
standard template is used.
"""
class Meta:
prefix = "superdjango_user"
[docs]class DynamicSettingsWrapper(object):
"""Facilitates the acquisition of settings dynamically, by wrapping ``settings.py``.
This class is automatically instantiated as ``SUPERDJANGO``, which makes the following example possible:
.. code-block:: python
from superdjango.conf import SUPERDJANGO
class Login(LoginView):
def get_form_class(self):
if SUPERDJANGO.USER_REMEMBER_ME_ENABLED:
return AuthenticationForm
return DefaultAuthenticationForm
Under the hood, ``SUPERDJANGO.USER_REMEMBER_ME_ENABLED`` is simply understood as
``getattr(settings, "SUPERDJANGO_USER_REMEMBER_ME_ENABLED")``.
.. note::
This is either really clever or really stupid.
"""
def __getattr__(self, item):
item = "SUPERDJANGO_%s" % item.upper()
return getattr(settings, item, None)
# noinspection PyMethodMayBeStatic
[docs] def get(self, name, default=None, prefix="SUPERDJANGO"):
"""Get the named value from ``settings.py``.
:param name: The name of the setting.
:type name: str
:param default: The default value.
:param prefix: The prefix to apply to the name of the setting.
:type prefix: str
"""
if prefix:
name = "%s_%s" % (prefix, name)
name = name.upper()
return getattr(settings, name, default)
# noinspection PyMethodMayBeStatic
[docs] def has(self, name, prefix="SUPERDJANGO"):
"""Indicates whether the named value exists ``settings.py`` *and* has a value.
:param name: The name of the setting.
:type name: str
:param prefix: The prefix to apply to the name of the setting.
:type prefix: str
"""
if prefix:
name = "%s_%s" % (prefix, name)
name = name.upper()
if hasattr(settings, name) and getattr(settings, name) is not None:
return True
return False
SUPERDJANGO = DynamicSettingsWrapper()