Skip to content

Fixes #49, Handle custom admin pages #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

* removed RemovedInDjango40Warning warning message, thanks to @Ivan-Feofanov
* fixed #49, fixes reverse url lookup to handle custom admin pages.

## [2.4.0] - 2021-02-08

Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
- [@tony](https://github.com/tony)
- [@tripliks](https://github.com/tripliks)
- [@Ivan-Feofanov](https://github.com/Ivan-Feofanov)
- [@bdnettleton](https://github.com/bdnettleton)
6 changes: 4 additions & 2 deletions inline_actions/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,15 +202,17 @@ def _execute_action(self, request, model_admin, action, obj, parent_obj=None):
if parent_obj is None: # InlineActionsMixin.MODEL_ADMIN:
# redirect to `changelist`
url = reverse(
'admin:{}_{}_changelist'.format(
'{}:{}_{}_changelist'.format(
self.admin_site.name,
obj._meta.app_label,
obj._meta.model_name,
),
)
else:
# redirect to `changeform`
url = reverse(
'admin:{}_{}_change'.format(
'{}:{}_{}_change'.format(
self.admin_site.name,
parent_obj._meta.app_label,
parent_obj._meta.model_name,
),
Expand Down
82 changes: 82 additions & 0 deletions test_proj/blog/custom_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from django.contrib import admin

from inline_actions.actions import DefaultActionsMixin, ViewAction
from inline_actions.admin import InlineActionsMixin, InlineActionsModelAdminMixin

from .admin import (
ChangeTitleActionsMixin,
TogglePublishActionsMixin,
UnPublishActionsMixin,
)
from .models import Article, AuthorProxy


class CustomAdminSite(admin.AdminSite):
site_header = "Custom admin"
site_title = "Custom Admin Portal"
index_title = "Welcome to Custom Administration"


custom_admin = CustomAdminSite(name="custom_admin")


class ArticleInline(
DefaultActionsMixin,
UnPublishActionsMixin,
TogglePublishActionsMixin,
InlineActionsMixin,
admin.TabularInline,
):
model = Article
fields = (
'title',
'status',
)
readonly_fields = (
'title',
'status',
)

def has_add_permission(self, request, obj=None):
return False


class ArticleNoopInline(InlineActionsMixin, admin.TabularInline):
model = Article
fields = (
'title',
'status',
)
readonly_fields = (
'title',
'status',
)

def get_inline_actions(self, request, obj=None):
actions = super(ArticleNoopInline, self).get_inline_actions(
request=request, obj=obj
)
actions.append('noop_action')
return actions

def noop_action(self, request, obj, parent_obj=None):
pass


@admin.register(AuthorProxy, site=custom_admin)
class AuthorMultipleInlinesAdmin(InlineActionsModelAdminMixin, admin.ModelAdmin):
inlines = [ArticleInline, ArticleNoopInline]
list_display = ('name',)
inline_actions = None


@admin.register(Article, site=custom_admin)
class ArticleAdmin(
UnPublishActionsMixin,
TogglePublishActionsMixin,
ChangeTitleActionsMixin,
ViewAction,
InlineActionsModelAdminMixin,
admin.ModelAdmin,
):
list_display = ('title', 'status', 'author')
48 changes: 48 additions & 0 deletions test_proj/blog/tests/test_inline_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,54 @@ def test_publish_action(admin_client, mocker, article):
assert article.status == Article.DRAFT


def test_custom_admin_publish_action(admin_client, mocker, article):
"""Test dynamically added actions using `get_actions()`"""
from ..admin import UnPublishActionsMixin

mocker.spy(UnPublishActionsMixin, 'get_inline_actions')
mocker.spy(UnPublishActionsMixin, 'publish')
mocker.spy(UnPublishActionsMixin, 'unpublish')
author = article.author
assert article.status == Article.DRAFT

author_url = reverse('custom_admin:blog_authorproxy_change', args=(author.pk,))
publish_input_name = (
'_action__articleinline__inline__publish__blog__article__{}'.format(article.pk)
)
unpublish_input_name = (
'_action__articleinline__inline__unpublish__blog__article__{}'.format(
article.pk
)
)

# open changeform
changeview = admin_client.get(author_url)
assert UnPublishActionsMixin.get_inline_actions.call_count > 0
assert publish_input_name in dict(changeview.form.fields)
assert "custom_admin" in changeview.request.path

# execute and test publish action
changeview = changeview.form.submit(name=publish_input_name).follow()
# not available in django 1.7
# article.refresh_from_db()
article = Article.objects.get(pk=article.pk)
assert publish_input_name not in dict(changeview.form.fields)
assert unpublish_input_name in dict(changeview.form.fields)
assert UnPublishActionsMixin.publish.call_count == 1
assert article.status == Article.PUBLISHED
assert changeview.request.path == author_url

# execute and test unpublish action
changeview = changeview.form.submit(name=unpublish_input_name).follow()
# article.refresh_from_db()
article = Article.objects.get(pk=article.pk)
assert publish_input_name in dict(changeview.form.fields)
assert unpublish_input_name not in dict(changeview.form.fields)
assert UnPublishActionsMixin.unpublish.call_count == 1
assert article.status == Article.DRAFT
assert changeview.request.path == author_url


def test_view_action(admin_client, mocker, article):
"""Test view action."""
from inline_actions.actions import ViewAction
Expand Down
47 changes: 47 additions & 0 deletions test_proj/blog/tests/test_model_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,53 @@ def test_publish_action(admin_client, mocker, article):
assert article.status == Article.DRAFT


def test_custom_admin_publish_action(admin_client, mocker, article):
"""Test dynamically added actions using `get_actions()`"""
from ..admin import UnPublishActionsMixin

mocker.spy(UnPublishActionsMixin, 'get_inline_actions')
mocker.spy(UnPublishActionsMixin, 'publish')
mocker.spy(UnPublishActionsMixin, 'unpublish')
assert article.status == Article.DRAFT

article_url = reverse('custom_admin:blog_article_changelist')
publish_input_name = (
'_action__articleadmin__admin__publish__blog__article__{}'.format(article.pk)
)
unpublish_input_name = (
'_action__articleadmin__admin__unpublish__blog__article__{}'.format(
article.pk,
)
)

# open changelist
changelist = admin_client.get(article_url)
assert UnPublishActionsMixin.get_inline_actions.call_count > 0
assert publish_input_name in dict(changelist.form.fields)
assert "custom_admin" in article_url

# execute and test publish action
changelist = changelist.form.submit(name=publish_input_name).follow()
# not available in django 1.7
# article.refresh_from_db()
article = Article.objects.get(pk=article.pk)
assert publish_input_name not in dict(changelist.form.fields)
assert unpublish_input_name in dict(changelist.form.fields)
assert UnPublishActionsMixin.publish.call_count == 1
assert article.status == Article.PUBLISHED
assert changelist.request.path == article_url

# execute and test unpublish action
changelist = changelist.form.submit(name=unpublish_input_name).follow()
# article.refresh_from_db()
article = Article.objects.get(pk=article.pk)
assert publish_input_name in dict(changelist.form.fields)
assert unpublish_input_name not in dict(changelist.form.fields)
assert UnPublishActionsMixin.unpublish.call_count == 1
assert article.status == Article.DRAFT
assert changelist.request.path == article_url


def test_view_action(admin_client, mocker, article):
"""Test view action."""
from inline_actions.actions import ViewAction
Expand Down
3 changes: 3 additions & 0 deletions test_proj/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from django.contrib import admin
from django.urls import path

from test_proj.blog.custom_admin import custom_admin

urlpatterns = [
path('admin/', admin.site.urls),
path('custom_admin/', custom_admin.urls),
]