Admin Interface — flask-peewee v0.1.0 documentation

### Navigation

- index
- next |
- previous |
- flask-peewee v0.1.0 documentation »

# Admin Interface

Many web applications ship with an “admin area”, where priveleged users can view and modify content. By introspecting your application’s models, flask-peewee can provide you with straightforward, easily-extensible forms for managing your application content.

Here’s a screen-shot of the admin dashboard:

## Getting started

To get started with the admin, there are just a couple steps:

1. Instantiate an `Auth` backend for your project – this component is responsible for providing the security for the admin area

   >     from flask import Flask

   >     from flaskext.auth import Auth
   >     from flaskext.db import Database

   >     app = Flask(__name__)
   >     db = Database(app)

   >     # needed for authentication
   >     auth = Auth(app, db)

2. Instantiate an `Admin` object

   >     # continued from above...
   >     from flaskext.admin import Admin

   >     admin = Admin(app, auth)

3. Register any `ModelAdmin` or `AdminPanel` objects you would like to expose via the admin

   >     # continuing... assuming "Blog" and "Entry" models
   >     admin.register(Blog) # register "Blog" with vanilla ModelAdmin
   >     admin.register(Entry, EntryAdmin) # register "Entry" with a custom ModelAdmin subclass

   >     # assume we have an "AdminPanel" called "NotePanel"
   >     admin.register_panel('Notes', NotePanel)

4. Call `Admin.setup()`, which registers the admin blueprint and configures the urls

   >     # after all models and panels are registered, configure the urls
   >     admin.setup()

Note

for a complete example, check the Example App which ships with the project

## Components of the Admin

The admin area is composed of three main components:

1. `ModelAdmin` instances, which expose create/edit/delete functionality for peewee models
2. `AdminPanel` instances, which appear in the dashboard and provide any additional functionality
3. `Admin` which serves as a central registry for `ModelAdmin` and `AdminPanel` instances

### ModelAdmin

Screenshot showing a typical `ModelAdmin` – this one exposing `Message` objects. Currently the list of messages is filtered to only list those by the user “coleifer”.

Typical usage:

    admin = Admin(app, auth)

    class Message(db.Model):
        user = ForeignKeyField(User)
        content = TextField()
        pub_date = DateTimeField(default=datetime.datetime.now)

        def __unicode__(self):
            return '%s: %s' % (self.user, self.content)

    class MessageAdmin(ModelAdmin):
        columns = ('user', 'content', 'pub_date',)

    admin.register(Message, MessageAdmin)

class `ModelAdmin`

  Class that determines how a peewee `Model` is exposed in the admin area. Provides a way of encapsulating model-specific configuration and behaviors.

  `columns`

    What columns should be displayed in the list index. By default if no columns are specified the `Model`‘s `__unicode__()` will be used.

    If a column is a model field, it will be “sortable”.

        class EntryAdmin(ModelAdmin):
            columns = ['title', 'pub_date', 'blog']

    Note

    columns can be either attributes of the model or callables on the model instance, though they will be called with no parameters.

  `paginate_by`

    How many records to paginate by when viewing lists of models, defaults to 20

  `get_query`()

    Return type: | A `SelectQuery` that represents the list of objects to expose

    Useful in the event that you would like to limit the objects shown via the admin.

        class UserAdmin(ModelAdmin):
            def get_query():
                # ask the auth system for the currently logged-in user
                current_user = self.auth.get_logged_in_user()

                # if they are not a superuser, only show them their own
                # account in the admin
                if not current_user.is_superuser:
                    return User.filter(id=current_user.id)

                # otherwise, show them all users
                return User.select()

  `get_object`(pk)

    Return type: | The model instance with the given pk, raising a `DoesNotExist` in the event the model instance does not exist.

  `get_form`()

    Provides a useful extension point in the event you want to define custom fields or custom validation behavior.

    Return type: | A wtf-peewee Form subclass that will be used when adding or editing model instances in the admin.

  `save_model`(instance, form, adding=False)

    Parameters: | instance – an unsaved model instance form – a validated form instance adding – boolean to indicate whether we are adding a new instance or saving an existing

    Method responsible for persisting changes to the database. Called by both the add and the edit views.

    Here is an example from the default `auth.User` `ModelAdmin`, in which the password is displayed as a sha1, but if the user is adding or edits the existing password, it re-hashes:

        def save_model(self, instance, form, adding=False):
            orig_password = instance.password

            user = super(UserAdmin, self).save_model(instance, form, adding)

            if orig_password != form.password.data:
                user.set_password(form.password.data)
                user.save()

            return user

  `get_urls`()

    Useful as a hook for extending `ModelAdmin` functionality with additional urls.

    Return type: | tuple of 2-tuples consisting of a mapping between url and view

  `get_url_name`(name)

    Since urls are namespaced, this function provides an easy way to get full urls to views provided by this ModelAdmin

### AdminPanel

Screenshot showing some examples of `AdminPanel` instances. One of these exposes a form where administrators can post “notes”, the other showing some aggregate data on user signups and site activity:

Typical usage:

    # panel code

    class NotePanel(AdminPanel):
        template_name = 'admin/notes.html'

        def get_urls(self):
            return (
                ('/create/', self.create),
            )

        def create(self):
            if request.method == 'POST':
                if request.form.get('message'):
                    Note.create(
                        user=auth.get_logged_in_user(),
                        message=request.form['message'],
                    )
            next = request.form.get('next') or self.dashboard_url()
            return redirect(next)

        def get_context(self):
            return {
                'note_list': Note.select().order_by(('created_date', 'desc')).paginate(1, 3)
            }

    admin.register_panel('Notes', NotePanel)

    <!-- template code -->
    {% extends "admin/panels/default.html" %}

    {% block panel_content %}
      {% for note in note_list %}
        <p>{{ note.user.username }}: {{ note.message }}</p>
      {% endfor %}
      <form method="post" action="{{ url_for(panel.get_url_name('create')) }}">
        <input type="hidden" value="{{ request.url }}" />
        <p><textarea name="message"></textarea></p>
        <p><button type="submit" class="small">Save</button></p>
      </form>
    {% endblock %}

class `AdminPanel`

  Class that provides a simple interface for providing arbitrary extensions to the admin. These are displayed as “panels” on the admin dashboard with a customizable template. They may additionally, however, define any views and urls.

  `template_name`

    What template to use to render the panel in the admin dashboard, defaults to `'admin/panels/default.html'`.

  `get_urls`()

    Mapping of urls and views that are provided by this panel.

    Return type: | Returns a tuple of 2-tuples mapping url to view

  `get_url_name`(name)

    Since urls are namespaced, this function provides an easy way to get full urls to views provided by this panel

    Parameters: | name – string representation of the view function whose url you want
    Return type: | String representing url

        <!-- taken from example -->
        <!-- will return something like /admin/notes/create/ -->
        {{ url_for(panel.get_url_name('create')) }}

  `get_template_name`()

    Return the template used to render this panel in the dashboard. By default simply returns the template stored under `AdminPanel.template_name`.

  `get_context`()

    Return the context to be used when rendering the dashboard template.

    Return type: | Dictionary

  `render`()

    Render the panel template with the context – this is what gets displayed in the admin dashboard.

### The Admin Class

class `Admin`

  Class used to expose an admin area at a certain url in your application.

  `__init__`(app, auth[, blueprint_factory[, template_helper[, prefix]]])

    Parameters: | app – flask application to bind admin to auth – `Auth` instance which will provide authentication blueprint_factory – an object that will create the `BluePrint` used by the admin template_helper – a subclass of `AdminTemplateHelper` that provides helpers and context to used by the admin templates prefix – url to bind admin to, defaults to `/admin`

  `register`(model[, admin_class=ModelAdmin])

    Parameters: | model – peewee model to expose via the admin admin_class – `ModelAdmin` or subclass to use with given model

  `register_panel`(title, panel)

    Parameters: | title – identifier for panel, example might be “Site Stats” panel – subclass of `AdminPanel` to display

  `setup`()

    Configures urls for models and panels, then registers blueprint.

    Warning

    call this after registering your models and panels

  `check_user_permission`(user)

    Parameters: | user – the currently logged-in user, exposed by the `Auth` instance

    Check whether the given user has permission to access to the admin area. The default implementation simply checks whether the `admin` field is checked.

        def check_user_permission(self, user):
            return user.admin

    Return type: | Boolean

  `get_urls`()

    Get a tuple of 2-tuples mapping urls to view functions that will be exposed by the admin. The default implementation looks like this:

        def get_urls(self):
            return (
                ('/', self.auth_required(self.index)),
            )

### Navigation

- index
- next |
- previous |
- flask-peewee v0.1.0 documentation »