from functools import update_wrapper from django.conf import settings from django.contrib import admin from django.core.urlresolvers import reverse from django.db import models from django.utils import importlib from django.utils.html import escape from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ from orchestra.models.utils import get_field_value from orchestra.utils.humanize import naturaldate from .decorators import admin_field def get_modeladmin(model, import_module=True): """ returns the modeladmin registred for model """ for k,v in admin.site._registry.iteritems(): if k is model: return v if import_module: # Sometimes the admin module is not yet imported app_label = model._meta.app_label for app in settings.INSTALLED_APPS: if app.endswith(app_label): app_label = app importlib.import_module('%s.%s' % (app_label, 'admin')) return get_modeladmin(model, import_module=False) def insertattr(model, name, value, weight=0): """ Inserts attribute to a modeladmin """ modeladmin = model if models.Model in model.__mro__: modeladmin = type(get_modeladmin(model)) # Avoid inlines defined on parent class be shared between subclasses # Seems that if we use tuples they are lost in some conditions like changing # the tuple in modeladmin.__init__ if not getattr(modeladmin, name): setattr(type(modeladmin), name, []) inserted_attrs = getattr(modeladmin, '__inserted_attrs__', {}) if not name in inserted_attrs: weights = {} if hasattr(modeladmin, 'weights') and name in modeladmin.weights: weights = modeladmin.weights.get(name) inserted_attrs[name] = [ (attr, weights.get(attr, 0)) for attr in getattr(modeladmin, name) ] inserted_attrs[name].append((value, weight)) inserted_attrs[name].sort(key=lambda a: a[1]) setattr(modeladmin, name, [ attr[0] for attr in inserted_attrs[name] ]) setattr(modeladmin, '__inserted_attrs__', inserted_attrs) def wrap_admin_view(modeladmin, view): """ Add admin authentication to view """ def wrapper(*args, **kwargs): return modeladmin.admin_site.admin_view(view)(*args, **kwargs) return update_wrapper(wrapper, view) def set_default_filter(queryarg, request, value): """ set default filters for changelist_view """ if queryarg not in request.GET: request_copy = request.GET.copy() if callable(value): value = value(request) request_copy[queryarg] = value request.GET = request_copy request.META['QUERY_STRING'] = request.GET.urlencode() @admin_field def admin_link(*args, **kwargs): instance = args[-1] obj = get_field_value(instance, kwargs['field']) if not getattr(obj, 'pk', None): return '---' opts = obj._meta view_name = 'admin:%s_%s_change' % (opts.app_label, opts.model_name) url = reverse(view_name, args=(obj.pk,)) extra = '' if kwargs['popup']: extra = 'onclick="return showAddAnotherPopup(this);"' return '%s' % (url, extra, obj) @admin_field def admin_colored(*args, **kwargs): instance = args[-1] field = kwargs['field'] value = escape(get_field_value(instance, field)) color = kwargs.get('colors', {}).get(value, 'black') value = getattr(instance, 'get_%s_display' % field)().upper() colored_value = '%s' % (color, value) if kwargs.get('bold', True): colored_value = '%s' % colored_value return mark_safe(colored_value) @admin_field def admin_date(*args, **kwargs): instance = args[-1] value = get_field_value(instance, kwargs['field']) if not value: return kwargs.get('default', '') return '{1}'.format( escape(str(value)), escape(naturaldate(value)), )