Skip to main content

Inline Changelists for Django

Project description

Inline Changelists for Django

Overview

Django Admin comes with inlines which allows you to display forms to edit related objects from the parent object’s change form. While it’s technically possible to use this infrastructure to display list of related objects, it gets hacky pretty fast.

Here’s where django-changelist-inline comes into play. It allows you to embed the standard list of objects as an inline on the parent object’s change form. Internally, it uses a subclass of ModelAdmin, which means you can customize the list as you’d normally do. Additionally, you can display links below the list of objects.

Usage Example

Let’s assume you have a Django project with two models - Thing and RelatedThing and that you want to display list of RelatedThing objects as an inline in Thing change form. The follwing snippet provides an example of how to implement that using django-changelist-inline:

# -*- coding: utf-8 -*-
from urllib.parse import urlencode

from django.contrib import admin
from django.urls import reverse
from django.utils.safestring import mark_safe
from django_changelist_inline import (
    ChangelistInline,
    ChangelistInlineAdmin,
    ChangelistInlineModelAdmin,
)

from testing.models import RelatedThing, Thing


@admin.register(RelatedThing)
class RelatedThingModelAdmin(admin.ModelAdmin):
    list_display = ('pk', 'name')


class RelatedThingChangelistInline(ChangelistInline):
    model = RelatedThing

    class ChangelistModelAdmin(ChangelistInlineModelAdmin):
        list_display = ('name', 'format_actions')
        list_display_links = None
        list_per_page = 5

        def get_queryset(self, request):
            return RelatedThing.objects.filter(thing=self.parent_instance)

        @mark_safe
        def format_actions(self, obj=None):
            if obj is None:
                return self.empty_value_display

            change_link_url = reverse(
                'admin:{app_label}_{model_name}_change'.format(
                    app_label=RelatedThing._meta.app_label,
                    model_name=RelatedThing._meta.model_name,
                ),
                args=[obj.pk],
            )

            return (
                f'<a class="button" href="{change_link_url}">'
                    'Edit'
                '</a>'
            )
        format_actions.short_description = 'Actions'

        @property
        def title(self):
            return 'Linked Related Things'

        @property
        def no_results_message(self):
            return 'No Related Things?'

        def get_add_url(self, request):
            result = super().get_add_url(request)
            if result is not None:
                return result + '?' + urlencode({
                    'thing': self.parent_instance.pk,
                })

            return result

        def get_show_all_url(self, request):
            result = super().get_show_all_url(request)
            if result is not None:
                return result + '?' + urlencode({
                    'thing': self.parent_instance.pk,
                })

            return result

        def get_toolbar_links(self, request):
            return (
                '<a href="https://www.bthlabs.pl/">'
                    'BTHLabs'
                '</a>'
            )


@admin.register(Thing)
class ThingModelAdmin(ChangelistInlineAdmin):
    inlines = (RelatedThingChangelistInline,)

API

ChangelistInline objects

The ChangelistInline class is the center piece of the API. It’s designed to be used in a ModelAdmin’s inlines.

In order for it to work, you’ll need to define the model property and embed ChangelistModelAdmin class, which should be a subclass of ChangelistInlineModelAdmin.

ChangelistInlineModelAdmin objects

The ChangelistInlineModelAdmin is a customized ModelAdmin subclass which provides sane defaults and additional functionality for inline changelists.

Changelist sanitization

This subclass overrides the following attributes and methods of ModelAdmin to provide sane defaults:

  • list_editable - set to empty tuple to disable editing of the list,

  • list_filter - set to empty tuple to disable filtering of the list,

  • search_fields - set to empty tuple to disable searching,

  • date_hierarchy - set to None,

  • sortable_by - set to empty tuple to disable sorting,

  • get_actions() - returns empty list to disable actions.

Additional functionality

To allow customization and to expose additional functionality, ChangelistInlineModelAdmin provides the following additional methods:

  • title property - returns the model’s verbose name by default.

  • no_results_message property - returns text to display in place of the table if no objects are fetched from the DB.

  • get_add_url(request) - returns URL for the model’s add form, if the user has the add permission. Return None to hide the add link.

  • get_show_all_url(request) - returns URL for the model’s changelist, if the user has the view permission. Return None to hide the show all link.

  • get_toolbar_links(request) - returns None by default. Override this to return string with additional <a/> elements to render in the toolbar. The return value is marked safe in the template.

ChangelistInlineAdmin objects

The ChangelistInlineAdmin class is a base class for ModelAdmin subclasses that use inline changelists.

ChangelistInlineAdminMixin

A mixin class that is used to properly configure changelist inlines in the parent ModelAdmin. Overrides get_inlines(request, obj=None) and get_inline_instances(request, obj=None) methods.

If you can’t use ChangelistInlineAdmin as you base class, you can use this mixin to enable inline changelists:

@admin.register(Thing)
class ThingModelAdmin(ChangelistInlineAdminMixin, MyBaseModelAdmin):
    ...

Author

django-changelist-inline is developed by Tomek Wójcik.

License

django-changelist-inline is licensed under the MIT License.

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-changelist-inline-1.0.2.tar.gz (8.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_changelist_inline-1.0.2-py3-none-any.whl (7.6 kB view details)

Uploaded Python 3

File details

Details for the file django-changelist-inline-1.0.2.tar.gz.

File metadata

  • Download URL: django-changelist-inline-1.0.2.tar.gz
  • Upload date:
  • Size: 8.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/2.0.0 pkginfo/1.7.1 requests/2.26.0 setuptools/44.0.0 requests-toolbelt/0.9.1 tqdm/4.61.2 CPython/3.8.10

File hashes

Hashes for django-changelist-inline-1.0.2.tar.gz
Algorithm Hash digest
SHA256 620eee2dc6df8c92c7a1e795b47fc4809bb8f84794133e98c9bef80c50f5095f
MD5 d274e75ff9292189b8496adb38cab3fa
BLAKE2b-256 95f9dd851deb1f9f9f21ad1da65fadded496a47d604c50b9a8d6c16b41c681e1

See more details on using hashes here.

File details

Details for the file django_changelist_inline-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: django_changelist_inline-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 7.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/2.0.0 pkginfo/1.7.1 requests/2.26.0 setuptools/44.0.0 requests-toolbelt/0.9.1 tqdm/4.61.2 CPython/3.8.10

File hashes

Hashes for django_changelist_inline-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b8ef766cd15000011b48ca83b2c224e1502ffc2d28921df3143cffaba11b8778
MD5 2296a1468819f93cdd2e102ce500c1da
BLAKE2b-256 fdeffc92610b72b2818cfbacfe597da04e01ac4013e580052a62c54ef0f09f4b

See more details on using hashes here.

Supported by

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