The basic workflow of Django’s admin is, in a nutshell, “select an object, then change it.” This works well for a majority of use cases. However, if you need to make the same change to many objects at once, this workflow can be quite tedious.
In these cases, Django’s admin lets you write and register “actions” – functions that get called with a list of objects selected on the change list page.
The “delete selected objects” action uses QuerySet.delete() for efficiency reasons, which has an important caveat: your model’s delete() method will not be called.
If you wish to override this behavior, you can override ModelAdmin.delete_queryset() or write a custom action which does deletion in your preferred manner – for example, by calling Model.delete() for each of the selected items.
For more background on bulk deletion, see the documentation on object deletion.
Writing action functions
First, we’ll need to write a function that gets called when the action is triggered from the admin. Action functions are regular functions that take three arguments:
- The current ModelAdmin
- An HttpRequest representing the current request,
- A QuerySet containing the set of objects selected by the user.
Our publish-these-articles function won’t need the ModelAdmin or the request object, but we will use the queryset:
def make_published(modeladmin, request, queryset):
queryset.update(status='p')
For the best performance, we’re using the queryset’s update method. Other types of actions might need to deal with each object individually; in these cases we’d iterate over the queryset:
for obj in queryset:
do_something_with(obj)
By default, this action would appear in the action list as “Make published” – the function name, with underscores replaced by spaces. That’s fine, but we can provide a better, more human-friendly name by using the action() decorator on the make_published function:
from django.contrib import admin
...
@admin.action(description='Mark selected stories as published')
def make_published(modeladmin, request, queryset):
queryset.update(status='p')
from django.contrib import admin
from myapp.models import Article
@admin.action(description='Mark selected stories as published')
def make_published(modeladmin, request, queryset):
queryset.update(status='p')
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'status']
ordering = ['title']
actions = [make_published]
admin.site.register(Article, ArticleAdmin)
Handling errors in actions¶
If there are foreseeable error conditions that may occur while running your action, you should gracefully inform the user of the problem. This means handling exceptions and using django.contrib.admin.ModelAdmin.message_user() to display a user friendly description of the problem in the response.
References:
https://django-import-export.readthedocs.io/en/latest/getting_started.html
No comments:
Post a Comment