Skip to content
Snippets Groups Projects
admin.py 4.95 KiB
Newer Older
Olivier Le Brouster's avatar
Olivier Le Brouster committed
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.contrib import admin
Dylann Cordel's avatar
Dylann Cordel committed
try:
    from django.urls import reverse
except ImportError:
    from django.core.urlresolvers import reverse
Olivier Le Brouster's avatar
Olivier Le Brouster committed
from django.utils import formats
from django.utils.translation import ugettext_lazy as _
from django.utils import six

try:
    from cms.admin.placeholderadmin import FrontendEditableAdminMixin, PlaceholderAdminMixin
except ImportError:
    # temporary django-cms backward compat
    from cms.admin.placeholderadmin import (
        FrontendEditableAdmin as FrontendEditableAdminMixin,
        PlaceholderAdmin as PlaceholderAdminMixin
    )

from newsbox.admin import NewsboxBaseAdmin, remove_field_from_fieldsets, add_fields_to_fieldset


class CustomModelCMSAdmin(admin.ModelAdmin):
Olivier Le Brouster's avatar
Olivier Le Brouster committed


def CustomModelCMSAdminFactory(
    object_title=None,
    edit_link_short_description=_('title'),
    edit_link_admin_order_field=None,
):
    class klass(CustomModelCMSAdmin):

        def edit_link_title(self, obj, func_or_attr=None):
            if func_or_attr is not None:
                if isinstance(func_or_attr, basestring):
                    if not hasattr(obj, func_or_attr):
                        raise ValueError(
                            'func_or_attr is a string, it needs to be'
                            ' an object attribute (eventualy a function)'
                        )

                    attr = getattr(obj, func_or_attr)
                    if callable(attr):
                        title = attr(obj)
                    else:
                        title = attr

                elif callable(func_or_attr):
                    title = func_or_attr(obj)
                else:
                    raise ValueError('func_or_attr needs to be either a string or a collable')

            else:
                title = six.text_type(obj)
            return title

        def edit_link(self, obj):
            """
            build the change list edit link
            """
            output = ''
            edit_url = reverse(
Dylann Cordel's avatar
Dylann Cordel committed
                'admin:%s_%s_change' % (obj._meta.app_label, obj._meta.model_name),
Olivier Le Brouster's avatar
Olivier Le Brouster committed
                args=[obj.pk])

            show_url = None
            if hasattr(obj, 'get_absolute_url'):
                show_url = obj.get_absolute_url()

            output = '<a class="edit" href="{edit_url}" title="{edit_label}"></a>'

            if show_url:
Dylann Cordel's avatar
Dylann Cordel committed
                output += ('<a class="title" href="{show_url}" target="_parent" '
                           'title="{show_label}">{title}</a>')
Olivier Le Brouster's avatar
Olivier Le Brouster committed
            else:
                output += '<span class="title">{title}</span>'

            return output.format(
                edit_url=edit_url, show_url=show_url, show_label=_("show object's page"),
Dylann Cordel's avatar
Dylann Cordel committed
                title=self.edit_link_title(obj, object_title),
                edit_label=_("edit object's parameters"))
Olivier Le Brouster's avatar
Olivier Le Brouster committed

        edit_link.allow_tags = True
        edit_link.short_description = edit_link_short_description
        edit_link.admin_order_field = edit_link_admin_order_field

        def get_list_display(self, request):
            list_display = super(CustomModelCMSAdmin, self).get_list_display(request)
            list_display = list(list_display)
            del list_display[0]
            list_display.insert(0, 'edit_link')
            return list_display

        def get_list_display_links(self, request, list_display):
Olivier Le Brouster's avatar
Olivier Le Brouster committed

    return klass


def newsbox_admin_title(obj):
    if not obj.newsbox_date:
        return six.text_type(obj)
Olivier Le Brouster's avatar
Olivier Le Brouster committed
    return '{date}<br/>{title}'.format(
        date=formats.date_format(obj.newsbox_date, 'DATE_FORMAT'),
        title=six.text_type(obj)
    )


class NewsboxCMSAdmin(
Dylann Cordel's avatar
Dylann Cordel committed
    # XXX: hvad TranslatableAdmin doesn't support admin_order_field on translated field
Olivier Le Brouster's avatar
Olivier Le Brouster committed
    # CustomModelCMSAdminFactory(edit_link_admin_order_field='newsbox_title'),
    CustomModelCMSAdminFactory(object_title=newsbox_admin_title,
                               edit_link_admin_order_field='newsbox_publication_start_date'),
Olivier Le Brouster's avatar
Olivier Le Brouster committed
    FrontendEditableAdminMixin,
    PlaceholderAdminMixin,
    NewsboxBaseAdmin
):

    def __init__(self, *args, **kwargs):
        # We manage the edit link ourself
        self.list_display_links = (None, )
        return super(NewsboxCMSAdmin, self).__init__(*args, **kwargs)
Olivier Le Brouster's avatar
Olivier Le Brouster committed
    def get_fieldsets(self, request, obj=None):
        fieldsets = super(NewsboxCMSAdmin, self).get_fieldsets(request, obj)
        remove_field_from_fieldsets('newsbox_body', fieldsets)
        add_fields_to_fieldset(
            ['newsbox_summary'],
            fieldsets,
Dylann Cordel's avatar
Dylann Cordel committed
            same_fieldset_as='newsbox_title',
            after_field='newsbox_date',
Olivier Le Brouster's avatar
Olivier Le Brouster committed
            replace_existing_field=True,
            remove_empty_fieldset=True,
        )
        return fieldsets

    def get_list_display(self, request):
        list_display = super(NewsboxCMSAdmin, self).get_list_display(request)
        if 'newsbox_date_short' in list_display:
            list_display.remove('newsbox_date_short')
Olivier Le Brouster's avatar
Olivier Le Brouster committed
        return list_display