django-orchestra/orchestra/admin/utils.py

186 lines
5.9 KiB
Python
Raw Permalink Normal View History

2014-09-17 10:32:29 +00:00
import datetime
2015-07-09 10:44:22 +00:00
import importlib
2014-10-09 17:04:12 +00:00
import inspect
2014-09-04 15:55:43 +00:00
from functools import wraps
2014-05-08 16:59:35 +00:00
from django.conf import settings
from django.contrib import admin
from django.core.exceptions import ObjectDoesNotExist
from django.urls import reverse, NoReverseMatch
2014-05-08 16:59:35 +00:00
from django.db import models
2014-08-19 18:59:23 +00:00
from django.shortcuts import redirect
2015-10-03 13:08:41 +00:00
from django.utils import timezone
from django.utils.html import escape, format_html
2014-05-08 16:59:35 +00:00
from django.utils.safestring import mark_safe
from orchestra.models.utils import get_field_value
2014-09-17 10:32:29 +00:00
from orchestra.utils import humanize
2014-05-08 16:59:35 +00:00
2014-07-24 09:53:34 +00:00
from .decorators import admin_field
2015-06-22 14:14:16 +00:00
from .html import monospace_format, code_format
2014-07-24 09:53:34 +00:00
2014-05-08 16:59:35 +00:00
def get_modeladmin(model, import_module=True):
""" returns the modeladmin registred for model """
2015-04-02 16:14:55 +00:00
for k,v in admin.site._registry.items():
2014-05-08 16:59:35 +00:00
if k is model:
2014-07-18 15:32:27 +00:00
return v
2014-05-08 16:59:35 +00:00
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)
2014-10-09 17:04:12 +00:00
def insertattr(model, name, value):
2014-05-08 16:59:35 +00:00
""" Inserts attribute to a modeladmin """
2014-10-09 17:04:12 +00:00
modeladmin = None
2015-04-14 15:22:01 +00:00
if issubclass(model, models.Model):
2014-10-09 17:04:12 +00:00
modeladmin = get_modeladmin(model)
modeladmin_class = type(modeladmin)
elif not inspect.isclass(model):
modeladmin = model
modeladmin_class = type(modeladmin)
else:
modeladmin_class = model
2014-05-08 16:59:35 +00:00
# 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__
2014-10-07 13:08:59 +00:00
if not getattr(modeladmin_class, name):
setattr(modeladmin_class, name, [])
2014-10-09 17:04:12 +00:00
setattr(modeladmin_class, name, list(getattr(modeladmin_class, name))+[value])
if modeladmin:
# make sure class and object share the same attribute, to avoid wierd bugs
setattr(modeladmin, name, getattr(modeladmin_class, name))
2014-05-08 16:59:35 +00:00
def wrap_admin_view(modeladmin, view):
""" Add admin authentication to view """
2014-09-04 15:55:43 +00:00
@wraps(view)
2014-05-08 16:59:35 +00:00
def wrapper(*args, **kwargs):
return modeladmin.admin_site.admin_view(view)(*args, **kwargs)
2014-09-04 15:55:43 +00:00
return wrapper
2014-05-08 16:59:35 +00:00
def set_url_query(request, key, value):
2014-05-08 16:59:35 +00:00
""" set default filters for changelist_view """
if key not in request.GET:
2014-07-21 15:43:36 +00:00
request_copy = request.GET.copy()
2014-05-08 16:59:35 +00:00
if callable(value):
value = value(request)
request_copy[key] = value
2014-07-21 15:43:36 +00:00
request.GET = request_copy
2014-05-08 16:59:35 +00:00
request.META['QUERY_STRING'] = request.GET.urlencode()
2014-08-19 18:59:23 +00:00
def action_to_view(action, modeladmin):
""" Converts modeladmin action to view function """
2014-09-04 15:55:43 +00:00
@wraps(action)
2014-08-19 18:59:23 +00:00
def action_view(request, object_id=1, modeladmin=modeladmin, action=action):
queryset = modeladmin.model.objects.filter(pk=object_id)
response = action(modeladmin, request, queryset)
if not response:
opts = modeladmin.model._meta
2014-10-09 17:04:12 +00:00
url = 'admin:%s_%s_change' % (opts.app_label, opts.model_name)
2014-08-19 18:59:23 +00:00
return redirect(url, object_id)
return response
return action_view
2014-09-18 15:07:39 +00:00
def change_url(obj):
if obj is not None:
cls = type(obj)
opts = obj._meta
2016-10-11 10:01:56 +00:00
if cls is models.DEFERRED:
opts = cls.__base__._meta
view_name = 'admin:%s_%s_change' % (opts.app_label, opts.model_name)
return reverse(view_name, args=(obj.pk,))
raise NoReverseMatch
2014-09-10 16:53:09 +00:00
2014-07-24 09:53:34 +00:00
@admin_field
2014-07-21 15:43:36 +00:00
def admin_link(*args, **kwargs):
2014-07-24 09:53:34 +00:00
instance = args[-1]
if kwargs['field'] in ('id', 'pk', '__str__'):
obj = instance
else:
try:
obj = get_field_value(instance, kwargs['field'])
except ObjectDoesNotExist:
return '---'
2014-07-24 09:53:34 +00:00
if not getattr(obj, 'pk', None):
return '---'
display_ = kwargs.get('display')
if display_:
display_ = getattr(obj, display_, display_)
2015-04-20 14:23:10 +00:00
else:
display_ = obj
2015-06-03 12:49:30 +00:00
try:
url = change_url(obj)
except NoReverseMatch:
# Does not has admin
return str(display_)
2014-07-24 09:53:34 +00:00
extra = ''
if kwargs['popup']:
extra = mark_safe('onclick="return showAddAnotherPopup(this);"')
2016-02-19 10:11:28 +00:00
title = "Change %s" % obj._meta.verbose_name
return format_html('<a href="{}" title="{}" {}>{}</a>', url, title, extra, display_)
2014-07-24 09:53:34 +00:00
@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 = '<span style="color: %s;">%s</span>' % (color, value)
if kwargs.get('bold', True):
colored_value = '<b>%s</b>' % colored_value
return mark_safe(colored_value)
@admin_field
def admin_date(*args, **kwargs):
instance = args[-1]
2015-10-03 13:08:41 +00:00
date = get_field_value(instance, kwargs['field'])
if not date:
2014-07-24 09:53:34 +00:00
return kwargs.get('default', '')
2015-10-03 13:08:41 +00:00
if isinstance(date, datetime.datetime):
natural = humanize.naturaldatetime(date)
2014-09-17 10:32:29 +00:00
else:
2015-10-03 13:08:41 +00:00
natural = humanize.naturaldate(date)
2015-10-04 19:57:00 +00:00
if hasattr(date, 'hour'):
date = timezone.localtime(date)
date = date.strftime("%Y-%m-%d %H:%M:%S %Z")
else:
date = date.strftime("%Y-%m-%d")
return format_html('<span title="{0}">{1}</span>', date, natural)
2014-09-10 16:53:09 +00:00
def get_object_from_url(modeladmin, request):
try:
object_id = int(request.path.split('/')[-3])
except ValueError:
return None
else:
return modeladmin.model.objects.get(pk=object_id)
def display_mono(field):
def display(self, log):
2016-03-11 12:19:34 +00:00
content = getattr(log, field)
return monospace_format(escape(content))
display.short_description = field
return display
2015-06-22 14:14:16 +00:00
def display_code(field):
def display(self, log):
return code_format(getattr(log, field))
display.short_description = field
return display