API Documentation

This section of the django-lass-metadata documentation is automatically generated from the code.

metadata - the LASS metadata system

The metadata app contains the generic metadata system used in LASS, which allows objects in the LASS model set to contain key-value stores of textual, image-based and other formats of metadata by inheriting a mixin and providing a subclass of the standard metadata models.

Metadata system

The metadata app is dedicated to the LASS metadata system, which allows various different strands of data (generally text, but also image-based and other formats) to be attached to items.

LASS uses the metadata system, for example, to provide shows with names and descriptions that have full recorded history and hooks for an approval system. It is also used to associate images (thumbnails and player insets) with podcasts.

Strands

Each model can have zero or more strands of metadata attached to it. Each strand is its own model (see below for more information on how to create a metadata provider model), and represents a specific collection of metadata on objects in the subject model.

Strands are indexed by name; an entire strand (as a dictionary-like object) can be retrieved from an implementor of MetadataSubjectMixin with object.metadata()['strand-name']. Generally, there will be a text strand containing all textual metadata, and an images strand containing thumbnail images and other related pictorial metadata.

Implementation

All metadata strands are implemented as key-value stores, the key store being implemented as one unified model for simplicity reasons and the value stores being separate for each strand for each model.

Two classes (metadata.mixins.MetadataSubjectMixin and metadata.models.GenericMetadata) provide the core framework for defining a metadata subject and a metadata strand. There are descendents of GenericMetadata available for specific commonly used strand types.

Examples

In the LASS project, examples of how to use the metadata system can be found in schedule.models.show, uryplayer.models.podcast and people.models.role.

Models

The metadata module contains several model definitions under metadata.models.

Metadata system models

MetadataKey

The MetadataKey model, which forms the key in the metadata key-value storage system.

class metadata.models.key.MetadataKey(*args, **kwargs)

Bases: lass_utils.models.type.Type

A metadata key, which defines the semantics of a piece of metadata.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MetadataKey.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

MetadataKey.objects = <django.db.models.manager.Manager object at 0x2051590>
MetadataKey.packageimagemetadata_set
MetadataKey.packagetextmetadata_set
GenericMetadata

Generic metadata base class.

class metadata.models.generic.GenericMetadata(*args, **kwargs)

Bases: people.mixins.approvable.ApprovableMixin, lass_utils.mixins.attachable.AttachableMixin, people.mixins.creatable.CreatableMixin, lass_utils.mixins.effective_range.EffectiveRangeMixin

An item of generic metadata.

NOTE TO IMPLEMENTORS: The final concrete instances of this class must have a field named ‘element’ that foreign key references the element of data to which the metadata is to be attached.

Any further implementors must also include a field named ‘value’ that stores the metadatum value.

class Meta

Bases: lass_utils.mixins.effective_range.Meta

abstract = False
GenericMetadata.approver
GenericMetadata.creator
GenericMetadata.key
GenericMetadata.kwargs = {}
GenericMetadata.objects = <model_utils.managers._PassThroughManager object at 0x2042e90>
TextMetadata

Models for the URY text metadata system.

To add metadata to a model, create a subclass of ‘Metadata’ for that model, descend the model from ‘MetadataSubjectMixin’, and fill out the methods identified in those two classes.

class metadata.models.text.TextMetadata(*args, **kwargs)

Bases: metadata.models.generic.GenericMetadata

Abstract base for items of textual metadata.

class Meta

Bases: metadata.models.generic.Meta

abstract = False
TextMetadata.approver
TextMetadata.creator
TextMetadata.key
TextMetadata.objects = <model_utils.managers._PassThroughManager object at 0x206ebd0>
ImageMetadata

Models for the URY image metadata system.

To add metadata to a model, create a subclass of ‘ImageMetadata’ for that model, descend the model from ‘ImageMetadataSubjectMixin’, and fill out the methods identified in those two classes.

class metadata.models.image.ImageMetadata(*args, **kwargs)

Bases: metadata.models.generic.GenericMetadata

Abstract base class for usages of images as metadata.

class Meta

Bases: metadata.models.generic.Meta

abstract = False
ImageMetadata.approver
ImageMetadata.creator
ImageMetadata.key
ImageMetadata.objects = <model_utils.managers._PassThroughManager object at 0x22c4290>

Other models

Type

Common base class for type-of models.

In LASS, the pattern of dynamic lookup tables representing types and categories of other objects is very prevalent; in order to make using these type models more convenient, we have a common abstract base class for them.

class metadata.models.type.Type(*args, **kwargs)

Bases: django.db.models.base.Model

An abstract base class for models representing types, categories or other keyed collections of other models.

class Meta
abstract = False
classmethod Type.get(identifier)

User-friendly type get function.

This function uses the caching system to cache the type for a short amount of time.

If the input is an integer, it will be treated as the target type’s primary key.

If the input is a string, it will be treated as the target type’s name (case-insensitively).

If the input is an instance of cls itself, it will simply be returned.

Else, TypeError will be raised.

Parameters:identifier (string, integer or an element of the called class) – an item of data representing the type to retrieve, or the type itself
Return type:an element of the called class
classmethod Type.get_or_404(*args, **kwargs)

Attempts to use get to retrieve an instance of this type, but returns Http404 instead of cls.DoesNotExist if no object of the given type exists.

Arguments are passed verbatim to get; see the docstring for get for parameter details.

Mixins

The metadata module contains mixins for adding metadata to existing models and suchlike.

Misc

Administration hooks

Administration system hooks for the metadata application.

class metadata.admin.MetadataKeyAdmin(model, admin_site)

Bases: django.contrib.admin.options.ModelAdmin

An adminstration snap-in for maintaining the list of metadata keys.

list_display = ('name', 'description', 'allow_multiple')
media
class metadata.admin.PackageAdmin(model, admin_site)

Bases: django.contrib.admin.options.ModelAdmin

An administration snap-in for maintaining the list of packages.

inlines = [<class 'metadata.admin.PackageTextMetadataInline'>, <class 'metadata.admin.PackageImageMetadataInline'>]
list_display = ('name', 'description', 'weight')
media
class metadata.admin.PackageImageMetadataInline(parent_model, admin_site)

Bases: metadata.admin_base.ImageMetadataInline

media
model

alias of PackageImageMetadata

class metadata.admin.PackageTextMetadataInline(parent_model, admin_site)

Bases: metadata.admin_base.TextMetadataInline

media
model

alias of PackageTextMetadata

metadata.admin.register(site)

Registers the metadata admin hooks with an admin site.

Unit tests

Test suite for the metadata package.

TODO: Cache tests

class metadata.tests.MetadataSubjectTest(*args, **kwargs)

Bases: django.db.models.base.Model, metadata.mixins.metadata_subject.MetadataSubjectMixin

Test metadata subject model.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MetadataSubjectTest.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

classmethod MetadataSubjectTest.make_foreign_key(nullable=False)
MetadataSubjectTest.metadata_strands()
MetadataSubjectTest.metadatasubjecttestpackageentry_set
MetadataSubjectTest.metadatasubjecttesttextmetadata_set
MetadataSubjectTest.objects = <django.db.models.manager.Manager object at 0x29101d0>
MetadataSubjectTest.packages()
MetadataSubjectTest.range_start()
MetadataSubjectTest.testimagemetadata_set
class metadata.tests.MultipleMetadataDictTest(methodName='runTest')

Bases: django.test.testcases.TestCase

Tests to see if the dictionary access method for metadata is functional on multiple-entry metadata.

fixtures = ['test_people', 'metadata_test']
test_image_get()

Tests whether getting image metadata works.

test_text_get()

Tests whether getting textual metadata works.

test_text_in()

Tests whether the metadata view supports ‘in’.

class metadata.tests.PackageTest(methodName='runTest')

Bases: django.test.testcases.TestCase

Tests to see if the metadata packages system is hooked in correctly and used as a fallback metadata source.

fixtures = ['test_people', 'metadata_test', 'package_test']
test_text()

Tests whether the package is used to provide default textual metadata.

class metadata.tests.SingleMetadataDictTest(methodName='runTest')

Bases: django.test.testcases.TestCase

Tests to see if the dictionary access method for metadata is functional on single-entry metadata.

fixtures = ['test_people', 'metadata_test']
test_default()

Tests whether default metadata works as expected.

test_effective_range()

Tests whether the single metadata getting system correctly respects the effective_from and effective_to bounds.

test_image_get()

Tests whether getting image metadata works.

test_text_get()

Tests whether getting textual metadata works.

test_text_in()

Tests whether the metadata view supports ‘in’.

admin_base

Base admin classes for metadata administration.

class metadata.admin_base.GeneralMetadataInline(parent_model, admin_site)

Bases: django.contrib.admin.options.TabularInline

Base inline class for anything that’s like metadata.

extra = 0
formfield_for_foreignkey(db_field, request, **kwargs)

Provides a form field for foreign keys.

Overrides the normal inline so that submitter and approver are set, by default, to the currently logged in user.

media
class metadata.admin_base.ImageMetadataInline(parent_model, admin_site)

Bases: metadata.admin_base.MetadataInline

Specialisation of MetadataInline for image metadata.

media
verbose_name = 'associated image'
verbose_name_plural = 'Associated images'
class metadata.admin_base.MetadataAdmin(model, admin_site)

Bases: django.contrib.admin.options.ModelAdmin

Base class for metadata admin-lets.

date_hierarchy = 'effective_from'
list_display = ('element', 'key', 'value', 'creator', 'approver', 'effective_from', 'effective_to')
media
class metadata.admin_base.MetadataInline(parent_model, admin_site)

Bases: metadata.admin_base.GeneralMetadataInline

Base inline class for metadata inline admin-lets.

fields = ('key', 'value', 'effective_from', 'effective_to', 'approver', 'creator')
media
class metadata.admin_base.PackageEntryInline(parent_model, admin_site)

Bases: metadata.admin_base.GeneralMetadataInline

Snap-in for editing package entries inline.

fields = ('package', 'effective_from', 'effective_to', 'approver', 'creator')
media
verbose_name = 'branding package'
verbose_name_plural = 'branding packages'
class metadata.admin_base.TextMetadataInline(parent_model, admin_site)

Bases: metadata.admin_base.MetadataInline

Specialisation of MetadataInline for text metadata.

media
verbose_name = 'associated text item'
verbose_name_plural = 'associated text items'

Hooks

Default hooks for the metadata system, as well as a function for running metadata hooks on queries.

exception metadata.hooks.HookFailureError(value)

Bases: exceptions.Exception

Exception raised when a metadata hook fails to fulfil a query, but not in a way that should halt execution.

exception metadata.hooks.QueryFailureError(value)

Bases: exceptions.Exception

Exception raised when a metadata query returns no results, but was expected to do so.

metadata.hooks.get_active_metadata(strand_set, key, date)

From the given queryset, extracts metadata matching the given key that was active at the given date.

metadata.hooks.get_strand_set(query)

Attempts to get a metadata strand related-set from the element of the given query, given the query’s requested strand.

metadata.hooks.handle_set(metadata, allow_multiple, query_type)

Handles a metadata set as required by the metadata’s multiplicity and the metadata query type.

Parameters:
  • metadata (QuerySet) – A set of metadata.
  • allow_multiple (bool) – Whether or not multiple values should be returned, in the case of the query type being VALUE.
  • query_type – The query type, which determines the behaviour expected of this function.
metadata.hooks.metadata_from_cache(query)

Given a metadata query, attempts to fulfil the request using the Django cache.

Parameters:query (metadata.query.MetadataQuery or similar object.) – The MetadataQuery this hook is trying to run.
metadata.hooks.metadata_from_default(query)

Given a metadata query, attempts to return the default value for the metadata key in the given strand.

Will raise metadata.hooks.HookFailureError on failure.

Parameters:query (metadata.query.MetadataQuery or similar object.) – The MetadataQuery this hook is trying to run.
metadata.hooks.metadata_from_package(query)

Given a metadata query, attempts to use the query element’s designated metadata packages to fulfil the request.

Will raise metadata.hooks.HookFailureError on failure.

Parameters:query (metadata.query.MetadataQuery or similar object.) – The MetadataQuery this hook is trying to run.
metadata.hooks.metadata_from_parent(query)

Given a metadata query, attempts to use the query element’s designated parent to fulfil the request.

Will raise metadata.hooks.HookFailureError on failure.

Parameters:query (metadata.query.MetadataQuery or similar object.) – The MetadataQuery this hook is trying to run.
metadata.hooks.metadata_from_strand_sets(query)

Given a metadata query, attempts to use the query element’s own metadata sets to fulfil the request.

Will raise metadata.hooks.HookFailureError on failure.

Parameters:query (metadata.query.MetadataQuery or similar object.) – The MetadataQuery this hook is trying to run.
metadata.hooks.run_query(query, hooks=None)

Runs a metadata query, optionally with the given set of hooks.

If hooks is None, the default set will be used. (See metadata.hooks.DEFAULT_HOOKS)

Parameters:
  • query (metadata.query.MetadataQuery or similar object.) – A metadata query.
  • hooks (iterable, for example list) – A set of hooks to run the query with.

Queries

In which a metadata query is defined.

class metadata.query.MetadataQuery(subject, date, key, strand='text', query_type=0)

Bases: object

An object that holds together all state required for a query for metadata on a metadata subject to be run.

For running a metadata query, see the metadata.hooks module.

Generally, however, most code shouldn’t need to use metadata queries directly. A sugary frontend is provided by metadata.mixins.MetadataSubjectMixin.

cache_key()

Returns a representation of the query that can be used as a cache key.

Return type:basestring
date

Returns the target metadata date of this query.

This will be the time of query creation if no date was specified.

initial_state()

Returns the value that should be the initial state of any running of this query.

join(old, new)

Join two successful query runnings in a way that satisfies the query’s requirements.

The old state is given precedence so, for example, trying to join two results for a value query on a single-value key will return the old state only.

Parameters:
  • old – the old answer to this query
  • new – the new answer to this query
replace(**kwargs)

Creates a new query representing the query with the initialising parameters in kwargs replacing their counterparts in this query.

Parameters:kwargs – A keyword argument dict of substitutions to make.
satisfied_by(result)

Given an intermediate result of a metadata query run, returns True if there need not be any more hook processing in order to get a valid answer to the query.

Parameters:result – the current result of a metadata query run