Source code for aristotle_mdr.register

"""
Aristotle-MDR concept register
------------------------------

This module allows developers to easily register new concept models with the core
functionality of Aristotle-MDR. The ``register_concept`` is a wrapper around three
methods that registers a new concept with the Django-Admin site, with the
Django-Autocomplete and with a class for a Haystack search index. This is all done
in a way that conforms to the permissions required for control item visibility.

Other methods in this module can be called, to highly customise how concepts are
used within the admin site and search, but should be considered internal methods
and future releases of Aristotle-MDR may break code that uses these methods.
"""
from __future__ import absolute_import
# import autocomplete_light

from django.contrib import admin
from django.utils.translation import ugettext_lazy as _

# from aristotle_mdr import autocomplete_light_registry as reg
from aristotle_mdr.search_indexes import conceptIndex

import aristotle_mdr.search_indexes as search_index

from haystack import connections
from haystack.constants import DEFAULT_ALIAS
from haystack import indexes

import logging
logger = logging.getLogger(__name__)
logger.debug("Logging started for " + __name__)


[docs]def register_concept(concept_class, *args, **kwargs): """ A handler for third-party apps to make registering extension models based on ``aristotle_mdr.models.concept`` easier. Sets up the version controls, search indexes, django administrator page and autocomplete handlers. All ``args`` and ``kwargs`` are passed to the called methods. For examples of what can be passed into this method review the other methods in ``aristotle_mdr.register``. Example usage (based on the models in the extensions test suite): register_concept(Question, extra_fieldsets=[('Question','question_text'),] """ register_concept_reversions(concept_class, *args, **kwargs) # must come before admin register_concept_admin(concept_class, *args, **kwargs) register_concept_search_index(concept_class, *args, **kwargs)
def register_concept_reversions(concept_class, *args, **kwargs): from reversion import revisions as reversion follows = kwargs.get('reversion', {}).get('follow', []) follows += [ '_concept_ptr', ] follow_classes = kwargs.get('reversion', {}).get('follow_classes', []) reversion.register(concept_class, follow=follows) for cls in follow_classes: reversion.register(cls)
[docs]def register_concept_search_index(concept_class, *args, **kwargs): """ Registers the given ``concept`` with a Haystack search index that conforms to Aristotle permissions. If the concept to be registered does not have a template for serving a search document, a basic document with just the basic fields from ``aristotle_mdr.models._concept`` will be used when indexing items. :param concept concept_class: The model that is to be registered for searching. """ class_name = "%s_%sSearchIndex" % (concept_class._meta.app_label, concept_class.__name__) model_index = kwargs.get('custom_search_index', create(concept_class)) setattr(search_index, class_name, model_index) search_index.registered_indexes.append(model_index) # Since we've added a new class, kill the index so it is rebuilt. connections[DEFAULT_ALIAS]._index = None
def create(cls): class SubclassedConceptIndex(conceptIndex, indexes.Indexable): def get_model(self): return cls return SubclassedConceptIndex
[docs]def register_concept_admin(concept_class, *args, **kwargs): """Registers the given ``concept`` with the Django admin backend based on the default ``aristotle_mdr.admin.ConceptAdmin``. Additional parameters are only required if a model has additional fields or references to other models. :param boolean auto_fieldsets: If no extra_fieldsets, when set to true this generates a list of fields for the admin page as "Extra fields for [class]" :param concept concept_class: The model that is to be registered :param list extra_fieldsets: Model-specific `fieldsets <https://docs.djangoproject.com/en/1.8/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fieldsets>`_ to be displayed. Fields in the tuples given should be those *not* defined by the base ``aristotle_mdr.models._concept`` class. :param list extra_inlines: Model-specific `inline <https://docs.djangoproject.com/en/1.8/ref/contrib/admin/#django.contrib.admin.ModelAdmin.inlines>`_ admin forms to be displayed. """ extra_fieldsets = kwargs.get('extra_fieldsets', []) auto_fieldsets = kwargs.get('auto_fieldsets', False) extra_inlines = kwargs.get('extra_inlines', []) extra_name_suggest_fields = kwargs.get('name_suggest_fields', []) # late import this as we call this in aristotle_mdr.admin and need it to be ready before we call this. from aristotle_mdr.admin import ConceptAdmin from aristotle_mdr.models import concept from django.db.models.fields.related import ManyToManyField, ManyToOneRel if not extra_fieldsets and auto_fieldsets: # returns every field that isn't in a concept field_names = concept._meta.get_all_field_names() + ['supersedes'] m2ms = [m[0] for m in concept_class._meta.get_m2m_with_model()] m2m_rel = [y.related_model for y in concept_class._meta.get_all_related_objects()] auto_fieldset = [] auto_inlines = [] for f in concept_class._meta.get_fields(): if f.name not in field_names and f.name not in concept_class.admin_page_excludes: auto_fieldset.append(f.name) if auto_fieldset: extra_fieldsets_name = _('Extra fields for %(class_name)s') % {'class_name': concept_class._meta.verbose_name.title()} extra_fieldsets = [(extra_fieldsets_name, {'fields': auto_fieldset})] for inline_field in auto_inlines: class AutoInline(admin.TabularInline): model=inline_field.related_model extra=0 extra_inlines.append(AutoInline) class SubclassedConceptAdmin(ConceptAdmin): model = concept_class if extra_name_suggest_fields: name_suggest_fields = extra_name_suggest_fields fieldsets = ConceptAdmin.fieldsets + extra_fieldsets inlines = ConceptAdmin.inlines + extra_inlines admin.site.register(concept_class, SubclassedConceptAdmin)
# def _register_concept_(concept_class, *args, **kwargs): # pass