config_models package#

Subpackages#

Submodules#

config_models.admin module#

Admin site models for managing ConfigurationModel subclasses.

class config_models.admin.ConfigurationModelAdmin(model, admin_site)#

Bases: ModelAdmin

ModelAdmin for ConfigurationModel subclasses

add_view(request, form_url='', extra_context=None)#
change_view(request, object_id, form_url='', extra_context=None)#
date_hierarchy = 'change_date'#
get_actions(request)#

Get the actions.

get_displayable_field_names()#

Return all field names, excluding reverse foreign key relationships.

get_list_display(request)#

Get the list display.

get_readonly_fields(request, obj=None)#

Hook for specifying custom readonly fields.

has_delete_permission(request, obj=None)#

Return True if the given request has permission to delete the given Django model instance, the default implementation doesn’t examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

property media#
revert(request, queryset)#

Admin action to revert a configuration back to the selected value

save_model(request, obj, form, change)#

Given a model instance save it to the database.

class config_models.admin.KeyedConfigurationModelAdmin(model, admin_site)#

Bases: ConfigurationModelAdmin

ModelAdmin for ConfigurationModel subclasses that use extra keys (i.e. they have KEY_FIELDS set).

add_view(request, form_url='', extra_context=None)#
date_hierarchy = None#

Edit link for the change view

get_list_display(request)#

Add a link to each row for creating a new row using the chosen row as a template

get_queryset(request)#

Annote the queryset with an ‘is_active’ property that’s true iff that row is the most recently added row for that particular set of KEY_FIELDS values. Filter the queryset to show only is_active rows by default.

list_filter = (<class 'config_models.admin.ShowHistoryFilter'>,)#
property media#
class config_models.admin.ShowHistoryFilter(request, params, model, model_admin)#

Bases: ListFilter

Admin change view filter to show only the most recent (i.e. the “current”) row for each unique key value.

choices(changelist)#

Returns choices ready to be output in the template.

expected_parameters()#

List the query string params used by this filter

has_output()#

Should this filter be shown?

parameter_name = 'show_history'#
queryset(request, queryset)#

Filter the queryset. No-op since it’s done by KeyedConfigurationModelAdmin

title = 'Status'#

config_models.apps module#

config_models Django application initialization.

class config_models.apps.ConfigModelsConfig(app_name, app_module)#

Bases: AppConfig

Configuration for the config_models Django application.

name = 'config_models'#

config_models.decorators module#

Decorators for model-based configuration.

config_models.decorators.require_config(config_model)#

View decorator that enables/disables a view based on configuration.

Arguments:
config_model (ConfigurationModel subclass): The class of the configuration

model to check.

Returns:
HttpResponse: 404 if the configuration model is disabled,

otherwise returns the response from the decorated view.

config_models.models module#

Django Model baseclass for database-backed configuration.

class config_models.models.ConfigurationModel(*args, **kwargs)#

Bases: Model

Abstract base class for model-based configuration

Properties:
cache_timeout (int): The number of seconds that this configuration

should be cached

KEY_FIELDS = ()#
class Meta#

Bases: object

abstract = False#
ordering = ('-change_date',)#
classmethod cache_key_name(*args)#

Return the name of the key to use to cache the current configuration

cache_timeout = 600#
change_date#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

changed_by#

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

changed_by_id#
classmethod current(*args)#

Return the active configuration entry, either from cache, from the database, or by creating a new empty entry (which is not persisted).

enabled#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

classmethod equal_to_current(json, fields_to_ignore=('id', 'change_date', 'changed_by'))#

Compares for equality this instance to a model instance constructed from the supplied JSON. This will ignore any fields in fields_to_ignore.

Note that this method cannot handle fields with many-to-many associations, as those can only be set on a saved model instance (and saving the model instance will create a new entry). All many-to-many field entries will be removed before the equality comparison is done.

Args:

json: json representing an entry to compare fields_to_ignore: List of fields that should not be compared for equality. By default includes id, change_date, and changed_by.

Returns: True if the checked fields are all equivalent, else False

fields_equal(instance, fields_to_ignore=('id', 'change_date', 'changed_by'))#

Compares this instance’s fields to the supplied instance to test for equality. This will ignore any fields in fields_to_ignore.

Note that this method ignores many-to-many fields.

Args:

instance: the model instance to compare fields_to_ignore: List of fields that should not be compared for equality. By default includes id, change_date, and changed_by.

Returns: True if the checked fields are all equivalent, else False

get_next_by_change_date(*, field=<django.db.models.fields.DateTimeField: change_date>, is_next=True, **kwargs)#
get_previous_by_change_date(*, field=<django.db.models.fields.DateTimeField: change_date>, is_next=False, **kwargs)#
classmethod is_enabled(*key_fields)#

Returns True if this feature is configured as enabled, else False.

Arguments:
key_fields: The positional arguments are the KEY_FIELDS used to identify the

configuration to be checked.

classmethod key_values(*key_fields, **kwargs)#

Get the set of unique values in the configuration table for the given key[s]. Calling cls.current(*value) for each value in the resulting list should always produce an entry, though any such entry may have enabled=False.

Arguments:
key_fields: The positional arguments are the KEY_FIELDS to return. For example if

you had a course embargo configuration where each entry was keyed on (country, course), then you might want to know “What countries have embargoes configured?” with cls.key_values(‘country’), or “Which courses have country restrictions?” with cls.key_values(‘course’). You can also leave this unspecified for the default, which returns the distinct combinations of all keys.

flat: If you pass flat=True as a kwarg, it has the same effect as in Django’s

‘values_list’ method: Instead of returning a list of lists, you’ll get one list of values. This makes sense to use whenever there is only one key being queried.

Return value:

List of lists of each combination of keys found in the database. e.g. [(“Italy”, “course-v1:SomeX+some+2015”), …] for the course embargo example

classmethod key_values_cache_key_name(*key_fields)#

Key for fetching unique key values from the cache

objects#
save(force_insert=False, force_update=False, using=None, update_fields=None)#

Clear the cached value when saving a new configuration entry

class config_models.models.ConfigurationModelManager(*args, **kwargs)#

Bases: Manager

Query manager for ConfigurationModel

current_set()#

A queryset for the active configuration entries only. Only useful if KEY_FIELDS is set.

Active means the means recent entries for each unique combination of keys. It does not necessaryily mean enbled.

with_active_flag()#

A query set where each result is annotated with an ‘is_active’ field that indicates if it’s the most recent entry for that combination of keys.

config_models.templatetags module#

Override the submit_row template tag to remove all save buttons from the admin dashboard change view if the context has readonly marked in it.

config_models.templatetags.submit_row(context)#

Overrides ‘django.contrib.admin.templatetags.admin_modify.submit_row’.

Manipulates the context going into that function by hiding all of the buttons in the submit row if the key readonly is set in the context.

config_models.urls module#

URLs for config_models.

config_models.utils module#

Utilities for working with ConfigurationModels.

config_models.utils.deserialize_json(stream, username)#

Given a stream containing JSON, deserializers the JSON into ConfigurationModel instances.

The stream is expected to be in the following format:
{ “model”: “config_models.ExampleConfigurationModel”,
“data”:
[
{ “enabled”: True,

“color”: “black” …

}, { “enabled”: False,

“color”: “yellow” …

]

}

If the provided stream does not contain valid JSON for the ConfigurationModel specified, an Exception will be raised.

Arguments:

stream: The stream of JSON, as described above. username: The username of the user making the change. This must match an existing user.

Returns: the number of created entries

config_models.utils.get_serializer_class(configuration_model)#

Returns a ConfigurationModel serializer class for the supplied configuration_model.

config_models.views module#

API view to allow manipulation of configuration models.

class config_models.views.AtomicMixin#

Bases: object

Mixin to provide atomic transaction for as_view.

classmethod as_view(**initkwargs)#

Overrides as_view to add atomic transaction.

classmethod create_atomic_wrapper(wrapped_func)#

Returns a wrapped function.

class config_models.views.ConfigurationModelCurrentAPIView(**kwargs)#

Bases: AtomicMixin, CreateAPIView, RetrieveAPIView

This view allows an authenticated user with the appropriate model permissions to read and write the current configuration for the specified model.

Like other APIViews, you can use this by using a url pattern similar to the following:

url(r'config/example_config$', ConfigurationModelCurrentAPIView.as_view(model=ExampleConfig))
authentication_classes = (<class 'rest_framework.authentication.SessionAuthentication'>,)#
get_object()#

Returns the object the view is displaying.

You may want to override this if you need to provide non-standard queryset lookups. Eg if objects are referenced using multiple keyword arguments in the url conf.

get_queryset()#

Get the list of items for this view. This must be an iterable, and may be a queryset. Defaults to using self.queryset.

This method should always be used rather than accessing self.queryset directly, as self.queryset gets evaluated only once, and those results are cached for all subsequent requests.

You may want to override this if you need to provide different querysets depending on the incoming request.

(Eg. return a list of items that is specific to the user)

get_serializer_class()#

Return the class to use for the serializer. Defaults to using self.serializer_class.

You may want to override this if you need to provide different serializations depending on the incoming request.

(Eg. admins get full serialization, others get basic serialization)

model = None#
perform_create(serializer)#
permission_classes = (<class 'config_models.views.ReadableOnlyByAuthors'>,)#
class config_models.views.ReadableOnlyByAuthors#

Bases: DjangoModelPermissions

Only allow access by users with add permissions on the model.

perms_map = {'DELETE': ['%(app_label)s.delete_%(model_name)s'], 'GET': ['%(app_label)s.add_%(model_name)s'], 'HEAD': ['%(app_label)s.add_%(model_name)s'], 'OPTIONS': ['%(app_label)s.add_%(model_name)s'], 'PATCH': ['%(app_label)s.change_%(model_name)s'], 'POST': ['%(app_label)s.add_%(model_name)s'], 'PUT': ['%(app_label)s.change_%(model_name)s']}#

Module contents#

Configuration models for Django allowing config management with auditing.