Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,37 @@ Exposing Models with the ModelAdmin

:rtype: A tuple as described above

.. py:method:: get_actions()

Defines mass actions, e.g. delete, export.

Returns a tuple containing:

* method responsible for action handling
* a dictionary with action configuration: name, url and title

Here's an example showing how to add block action:

.. code-block:: python

class UserModelAdmin(ModelAdmin):
def get_actions(self):
return super().get_actions() + (
(self.block, {'name': 'block', 'url': '/block/', 'title': "Block"}),
)

def block(self):
if request.method == 'GET':
id_list = request.args.getlist('id')
else:
id_list = request.form.getlist('id')

query = self.model.select().where(self.pk << id_list)

# block selected users and return a response
# ...

:rtype: A tuple as described above

Extending admin functionality using AdminPanel
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
22 changes: 16 additions & 6 deletions flask_peewee/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,20 @@ def get_query(self):
def get_object(self, pk):
return self.get_query().where(self.pk==pk).get()

def get_actions(self):
return (
(self.delete, {'name': 'delete', 'url': '/delete/', 'title': 'Delete'}),
(self.export, {'name': 'export', 'url': '/export/', 'title': 'Export'}),
)

def get_urls(self):
actions_urls = [(info['url'], method)
for method, info in self.get_actions()]

return (
('/', self.index),
('/add/', self.add),
('/delete/', self.delete),
('/export/', self.export),
) + tuple(actions_urls) + (
('/<pk>/', self.edit),
('/_ajax/', self.ajax_list),
)
Expand Down Expand Up @@ -219,12 +227,14 @@ def index(self):
# create a paginated query out of our filtered results
pq = PaginatedQuery(query, self.paginate_by)

# actions
if request.method == 'POST':
id_list = request.form.getlist('id')
if request.form['action'] == 'delete':
return redirect(url_for(self.get_url_name('delete'), id=id_list))
action = request.form['action']
if action in [info['name'] for method, info in self.get_actions()]:
id_list = request.form.getlist('id')
return redirect(url_for(self.get_url_name(action), id=id_list))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we raise a 404 if the action is not recognized?

else:
return redirect(url_for(self.get_url_name('export'), id=id_list))
abort(404)

return render_template(self.templates['index'],
model_admin=self,
Expand Down
8 changes: 6 additions & 2 deletions flask_peewee/templates/admin/models/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
{% block tab_index_class %}active{% endblock %}

{% block extra_tabs %}
{% set model_admin_actions = model_admin.get_actions() %}
{% if model_admin_actions %}
<li class="dropdown" style="float:right">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">With selected... <span class="caret" /></a>
<ul class="dropdown-menu pull-right">
<li><a href="#" onclick="Admin.index_submit('export');">Export</a></li>
<li><a href="#" onclick="Admin.index_submit('delete');">Delete</a></li>
{% for method, info in model_admin_actions %}
<li><a href="#" onclick="Admin.index_submit('{{ info.name }}');">{{ info.title }}</a></li>
{% endfor %}
</ul>
</li>
{% endif %}
{% include "admin/includes/filter_dropdown.html" %}
{% endblock %}

Expand Down