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:
To get started with the admin, there are just a couple steps:
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)
Instantiate an Admin object
# continued from above... from flaskext.admin import Admin admin = Admin(app, auth)
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)
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
The admin area is composed of three main components:
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 that determines how a peewee Model is exposed in the admin area. Provides a way of encapsulating model-specific configuration and behaviors.
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.
How many records to paginate by when viewing lists of models, defaults to 20
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()
Return type: | The model instance with the given pk, raising a DoesNotExist in the event the model instance does not exist. |
---|
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. |
---|
Parameters: |
|
---|
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
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 |
---|
Since urls are namespaced, this function provides an easy way to get full urls to views provided by this ModelAdmin
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 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.
What template to use to render the panel in the admin dashboard, defaults to 'admin/panels/default.html'.
Mapping of urls and views that are provided by this panel.
Return type: | Returns a tuple of 2-tuples mapping url to view |
---|
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')) }}
Return the template used to render this panel in the dashboard. By default simply returns the template stored under AdminPanel.template_name.
Return the context to be used when rendering the dashboard template.
Return type: | Dictionary |
---|
Render the panel template with the context – this is what gets displayed in the admin dashboard.
Class used to expose an admin area at a certain url in your application.
Parameters: |
|
---|
Parameters: |
|
---|
Parameters: |
|
---|
Configures urls for models and panels, then registers blueprint.
Warning
call this after registering your models and panels
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 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)),
)