Optional, replaceable extras

In the installation and basic usage we covered the bare minimum required to display plain text links to the admin. We can, of course, do better than that, and django-adminlinks comes with a few bits and pieces to do so. None of them are required, or even enabled by default, and all of them are replaceable.

Making things modal

Though it is inevitably not perfect, we can make the UX a little better by allowing users to edit things in-place, via the included modal iframe.

Using the provided JavaScript

Exactly like the bundled Stylesheets template tag, there’s a template tag for rendering the bundled JavaScript. The same caveats about django-sekizai and django-compressor apply:

{% load adminlinks_assets %}
<!doctype html>
<html>
    <head>
        [...]
    </head>
    <body>
    [...]
        {% render_adminlinks_js %}
    </body>
</html>

Which will output:

{% if should_load_assets %}
    {% load static %}
    <script type="text/javascript" src="{% static 'admin/js/jquery.min.js' %}{% if debug %}?cachebusting={% now "u" %}{% endif %}"></script>
    <script type="text/javascript" src="{% static 'adminlinks/js/jquery.fancyiframe.js' %}{% if debug %}?cachebusting={% now "u" %}{% endif %}"></script>
    <script type="text/javascript" src="{% static 'adminlinks/js/adminlinks.js' %}{% if debug %}?cachebusting={% now "u" %}{% endif %}"></script>
{% endif %}

As you can see, the JavaScript is a little bit more involved. It uses the jQuery which comes with Django, and a script of my own wrangling, to display an <iframe> in a modal box. It hooks up all classes of django-adminlinks--btn to this modal box – this CSS class is applied as a namespace to all the links Here’s an example of it being used with the default CSS to do per-field editing of the title.

_images/modal.gif

Note

The modal window has been sped up here to keep the animated GIF small, and the admin is in popup mode thanks to fix_admin_popups().

Patching the standard ModelAdmin

If you’re making use of the bundled JavaScript, through the template tag or otherwise, you’ll probably want to alter the behaviour of the Django ModelAdmin instances in an effort to better support the modal-editing. We can extend the behaviour like so:

from django.contrib import admin
from adminlinks.admin import AdminlinksMixin
from myapp.models import MyModel

# At it's most simple, mixing in with the default modeladmin.
class MyModelAdmin(AdminlinksMixin, admin.ModelAdmin):
    list_display = ['my_field', 'my_other_field']
admin.site.register(MyModel, MyModelAdmin)

Or, for the slightly more complex usage of replacing a third-party admin:

from django.contrib import admin
from adminlinks.admin import AdminlinksMixin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin

# Replacing an existing Modeladmin
try:
    admin.site.unregister(User)
except admin.NotRegistered:
    pass

class MyUserAdmin(AdminlinksMixin, UserAdmin):
    pass
admin.site.register(User, MyUserAdmin)

For more complex admins, or different ways of handling displaying things (such as using jQuery ajaxForm, or one of the many other modal boxes) you’ll have to go off the beaten track and drop some/most of the provided stuff. Any suggestions for how to make it more flexible, do get in contact and explain.

Editing field subsets

If your intention is to use the edit field template tag:

{% render_edit_field_button object 'title' %}

You’ll need to amend your ModelAdmin to support the dynamic generation of that form, using the AdminlinksMixin, which updates the standard get_urls() to expose the change_field_view()

Success responses

To allow our bundled JavaScript’s modal box to automatically close after a non-idempotent action (eg: add/change/delete), we need to override the existing modeladmin methods response_add(), response_change() and delete_view() to handle sending a message to the modal window. That too is covered by including AdminlinksMixin.

Simplifying the AdminSite visual clutter

If you’re aiming for doing everything via the front-end, using the template tags to their fullest potential, you may want to get rid of some of the visual noise the admin provides (header, breadcrumbs, etc). Add the following to your TEMPLATE_CONTEXT_PROCESSORS to make it behave as if it were in a popup, reducing the visual context appropriately:

TEMPLATE_CONTEXT_PROCESSORS = (

    # These are other context processors we probably already have ...
    "django.contrib.auth.context_processors.auth",
    "django.core.context_processors.media",
    "django.core.context_processors.static",
    "django.core.context_processors.request",

    # This is our new context processor!
    "adminlinks.context_processors.fix_admin_popups",
)

See fix_admin_popups() for more.