Code


Version 4 (modified by abki, 16 months ago) (diff)

add link to the project page

Admin revamp project.

Planning to remove this editorial content

Basically what the admin lacks is hooks to extend it as needed and in unexpected fashion, while it's always possible to extend it, current methods are considered hacks and introduce code that is not easy to maintain.

What we propose here is a revamp of the the admin app looking for minimal work to customize the admin, striving for reusability and maintenability while still making it possible to:

  • extend every pages of the admin in an arbitrary fashion without having to rely on Javascript hacks
  • make it possible to add views easily
  • Refresh the design and make it responsive

Big picture

The idea is taken from PHP-Nuke which blew some minds in its time:

  • Use of a class per page
  • Populate templates with widgets

Current admin limitations

  • Current workflow for most page is to customize the pages of the admins are the following:
    • most common way: Override ModelAdmin or Admin class methods, inject needed variables in template context and then override the templates: this can be made simpler, overriding templates is not considered future proof and can be made simpler
    • There are hooks to insert custom code (filter spec, admin actions) but it's predefined, not flexible and bound to features already defined in the admin. What if one wants a custom sidebar that fills the form dynamically from generated list of templates ?
    • Insert Javascript, this is the most flexible way to extend the admin, it's hacky and promotes creation of code that might not be accessible.
    • Adding a view is two way process a) subclass get_urls, add the url b) create a new method of ModelAdmin as view

Following limitations are from my own and might not reflect reality don't hesitate to comment or strip if it's not appropriate:

  • In a context where you have several admin sites or experiences because of different user permissions or settings, templates are the only reusable part. You can create functions to encapsulate some functionality but there is no canvas for that and can become a bit messy with a big file named like admin_views_utils.py.
  • ...

Features

  • Same features as current admin
  • Responsive
  • Use class-based-views throughout

Features that need further definition

  • Each page is a widget composition
  • Each widget is class

Examples of Admin Extension in the Wild

In alphabetical order:

Built on top of admin-tools:

Simple Bootstrap Themes:

Pros

  • No more hacks: Offers a clear canvas to extend the admin
  • More reusable components for Django
  • The framework/application upon which HydroAdmin is built can be used to create frontends just like PHP-Nuke making Django even-more accessible (and maybe even to non-developpers)
  • No more monkey-patching
  • ...

Cons

  • Backward incompatible
  • More layer in view infrastructure
  • No more hacks
  • ...

Code layout

  • Hydro this is an application framework with all of what is needed to create an application using the page/widget classes
    • Hydro is named like that because of wrong assumption, it goes as follow: I thought that nuke was another name for nucelar bomb, what is better than an nuclear bomb is a Hydrogen bomb, it doesn't work because nuke is used for both hydrogen nukes and plutonium nukes.
    • Another name ?
  • HydroAdmin this is an example app of the Hydro application that use the page/widget classes to build a backend equivalent in feature to current admin
    • HydroAdmin is the project name, eventually it will be named admin just like newforms became forms

About using boostrap:

  • is the licensing Ok ?
  • should it be embedded compiled or as a git submodule ?

Current code of the widget compositing framework at github

Example code

The following is deprecated, have a look at examples in the code repository of the project.


Rough draft of how page class and widget classes works

Current admin index would be implemented in hydro like that:

class AdminMainPage(OneColumnLayout):

    template = 'admin/index.html'
    widgets = [
        SplitPane("subheader", Menu(), Login()),
        SplitPane("main", Applications(), RecentChanges()),
        QuickLinks(),
    ]

   def __init__(self, *args, **kwargs):
       super(AdminMainPage, self).__init__(*args, **kwargs)
       self.apps = []

   def register(self, app):
       self.apps.append(app)

A frontend can be implemented like this:

class FrontPage(TwoColumnLayout):

    path = '/'
    template = 
    header = [Menu(), Login()]
    column_one = [Menu()]
    column_two = [FrontPageArticleList()]
    footer = [QuickLinks(), Credits()]

The change list is similar in fashion to the above examples.

Here is an example widget class:

class Applications(Widget):

    javascript = ['frontpage.js']
    css = ['frontpage.css']
    template = 'frontpage_article_list.html'
    
    def get_context(self, page, request):
        return {'articles': Article.object.all() }

Another example:

class FrontPageArticleList(Widget):

    template = 'apps.html'
    
    def get_context(self, page, request):
        return {'apps': page.apps }

Comments

  • Instead of proposing a specific solution, let's focus on identifying the issues that the current admin has without the editorial content. For example "no more monkey patching" as a pro without an actual example of functionality that can not be done without monkey patching the admin is baseless. –Travis Swicegood
  • Is it OK to allow both a string and a list of strings as argument/attributes, like it's done for templates ? that way the above examples can be made simpler by dropping some brackets, it's bit more documentation but when you have to do lot of those it makes things easier I think.
  • ...

I put here comments about the current code:

  • Should widegts get access to outer level contexts ? -1

Don't hesitate to comment!