Skip to main content

django-inline-actions adds actions to the InlineModelAdmin.

Project description

https://img.shields.io/pypi/v/django-inline-actions.svg Build Status Coverage https://img.shields.io/pypi/pyversions/django-inline-actions.svg https://img.shields.io/pypi/status/django-inline-actions.svg https://img.shields.io/pypi/l/django-inline-actions.svg

django-inline-actions adds actions to the InlineModelAdmin and ModelAdmin changelist.

Screenshot

https://raw.githubusercontent.com/escaped/django-inline-actions/master/example_changelist.png https://raw.githubusercontent.com/escaped/django-inline-actions/master/example_inline.png

Installation

Note: For now only django<1.11 is supported. Pull Requests are welcome!

  1. Install django-inline-actions

    pip install django-inline-actions
  2. Add inline_actions to your INSTALLED_APPS.

Integration

Add the InlineActionsModelAdminMixin to your ModelAdmin. If you want to have actions on your inlines, add the InlineActionMixin to your InlineModelAdmin. Each action is implemented as a method on the ModelAdmin/InlineModelAdmin and has the following signature

def action_name(self, request, obj, parent_obj=None)
  1. request - current request

  2. obj - instance on which the action was triggered

  3. parent_obj - instance of the parent model, only set on inlines

and should return None to return to the current changeform or a HttpResponse. Finally, add your method name to the inline_actions property. If you want to disable the Actions column, explicitly set inline_actions = None. To add your actions dynamically, you can use the method get_inline_actions(self, request, obj=None) instead.

This module is bundled with two actions for viewing (inline_actions.actions.ViewAction) and deleting (inline_actions.actions.DeleteAction). Just add these classes to your admin and you’re done.

Additionally, you can add methods to generate a custom label and css classes per object. If you have an inline action called action_name then you can define

def get_action_name_label(self, obj):
    return 'some string'


def get_action_name_css(self, obj):
    return 'some string'
  1. obj - instance on which the action was triggered

Each defined method has to return a string.

Example 1

Imagine a simple news application with the following admin.py.

from django.contrib import admin
from inline_actions.admin import InlineActionsMixin
from inline_actions.admin import InlineActionsModelAdminMixin

from .models import Article, Author


class ArticleInline(InlineActionsMixin,
                    admin.TabularInline):
    model = Article
    inline_actions = []

    def has_add_permission(self):
        return False


@admin.register(Author)
class AuthorAdmin(InlineActionsModelAdminMixin,
                  admin.ModelAdmin):
    inlines = [ArticleInline]
    list_display = ('name',)


@admin.register(Article)
class AuthorAdmin(admin.ModelAdmin):
    list_display = ('title', 'status', 'author')

We now want to add two simple actions (view, unpublish) to each article within the AuthorAdmin. The view action redirects to the changeform of the selected instance

from django.core.urlresolvers import reverse
from django.shortcuts import redirect


class ArticleInline(InlineActionsMixin,
                    admin.TabularInline):
    # ...
    inline_actions = ['view']
    # ...

    def view(self, request, obj, parent_obj=None):
        url = reverse(
            'admin:{}_{}_change'.format(
                obj._meta.app_label,
                obj._meta.model_name,
            ),
            args=(obj.pk,)
        )
        return redirect(url)
    view.short_description = _("View")

Since unpublish depends on article.status we must use get_inline_actions to add this action dynamically.

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


class ArticleInline(InlineActionsMixin,
                    admin.TabularInline):
    # ...
    def get_inline_actions(self, request, obj=None):
        actions = super(ArticleInline, self).get_inline_actions(request, obj)
        if obj:
            if obj.status == Article.PUBLISHED:
                actions.append('unpublish')
        return actions

    def unpublish(self, request, obj, inline_obj):
        inline_obj.status = Article.DRAFT
        inline_obj.save()
        messages.info(request, _("Article unpublished"))
    unpublish.short_description = _("Unpublish")

Adding inline_actions to the changelist works similar. See the sample project for further details (test_proj/blog/admin.py).

Example 2

If we want only one button, we can alternatively create single an action toggle_publish that will be used to change the publish status.

def toggle_publish(self, request, obj, parent_obj=None):
    if obj.status == Article.DRAFT:
        obj.status = Article.PUBLISHED
    else:
        obj.status = Article.DRAFT

    obj.save()
    status = 'unpublished' if obj.status == Article.DRAFT else 'published'
    messages.info(request, _("Article {}.".format(status)))

This might leave the user with an ambiguous button label as it will be called Toggle publish. We can easily modify it by adding:

def get_toggle_publish_label(self, obj):
    label = 'publish' if obj.status == Article.DRAFT else 'unpublish'
    return 'Toggle {}'.format(label)

So assuming an object in row has DRAFT status, then the button label will be Toggle publish and Toggle unpublish otherwise.

We can go even fancier when we create a method that will add css classes for each object depending on a status like:

def get_toggle_publish_css(self, obj):
    return (
        'btn-green' if obj.status == Article.DRAFT else 'btn-red')

You can make it more eye-candy by using btn-green that makes your button green and btn-red that makes your button red. Or zou can use those classes to add some javascript logic (i.e. confirmation box).

Example Application

You can see django-inline-actions in action using the bundled test application test_proj. I recommend to use a virtualenv.

git clone https://github.com/escaped/django-inline-actions.git
cd django-inline-actions/
pip install Django
pip install -e .
cd test_proj
./manage.py migrate
./manage.py createsuperuser
./manage.py runserver

Open http://localhost:8000/admin/ in your browser and create an author and some articles.

Migration to 1.0.0

Version 1.0.0 adds support for the admin changelist. Since the django ModelAdmin already has its own action handling, this release introduces breaking changes. Basically action has been renamed to inline_action in all method and property names.

type

old_name

new_name

property

actions

inline_actions

method

get_actions

get_inline_actions

method

render_actions

render_inline_actions

Since an action can now be called from a ModelAdmin or an InlineAdmin the signature of each action has changed to def action_name(self, request, obj, parent_obj=None). See Integration for further details.

If you do not want to use inline_actions on a changelist, you must deactivate its rendering explicitly

class Foo(InlineActionsModelAdminMixin, admin.ModelADmin):
   inline_actions = None
   # ...

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-inline-actions-1.1.0.tar.gz (11.1 kB view details)

Uploaded Source

Built Distribution

django_inline_actions-1.1.0-py2.py3-none-any.whl (12.3 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file django-inline-actions-1.1.0.tar.gz.

File metadata

File hashes

Hashes for django-inline-actions-1.1.0.tar.gz
Algorithm Hash digest
SHA256 4527e1e6206b8d2368276ecd463e411fa6abf53871e185d86e237595cdb842f9
MD5 e2232e4c394fe037e3ce075636282205
BLAKE2b-256 5008bdc1338066def98d014e8e0fd9ec2f9f0c9877ecdc22ef753c06f2f6ddc0

See more details on using hashes here.

File details

Details for the file django_inline_actions-1.1.0-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for django_inline_actions-1.1.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 507c5be8fad5ca4b7b330f3ef3ff055cdad5e385fd0e58aaab838780617aa2d7
MD5 80afb37a4a8596007bbd5f677e55cf03
BLAKE2b-256 ff544ffd92e65582797a16e8e30343bc73f2f13778596b0a5527a1672b81ebff

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page