Wednesday, July 7, 2021

Django Admin Custom Action methods

Actions that provide intermediate pages


By default, after an action is performed the user is redirected back to the original change list page. However, some actions, especially more complex ones, will need to return intermediate pages. For example, the built-in delete action asks for confirmation before deleting the selected objects.


To provide an intermediary page, return an HttpResponse (or subclass) from your action. For example, you might write an export function that uses Django’s serialization functions to dump some selected objects as JSON:


from django.core import serializers

from django.http import HttpResponse


def export_as_json(modeladmin, request, queryset):

    response = HttpResponse(content_type="application/json")

    serializers.serialize("json", queryset, stream=response)

    return response



Generally, something like the above isn’t considered a great idea. Most of the time, the best practice will be to return an HttpResponseRedirect and redirect the user to a view you’ve written, passing the list of selected objects in the GET query string. This allows you to provide complex interaction logic on the intermediary pages. For example, if you wanted to provide a more complete export function, you’d want to let the user choose a format, and possibly a list of fields to include in the export. The best thing to do would be to write a small action that redirects to your custom export view:


from django.contrib.contenttypes.models import ContentType

from django.http import HttpResponseRedirect


def export_selected_objects(modeladmin, request, queryset):

    selected = queryset.values_list('pk', flat=True)

    ct = ContentType.objects.get_for_model(queryset.model)

    return HttpResponseRedirect('/export/?ct=%s&ids=%s' % (

        ct.pk,

        ','.join(str(pk) for pk in selected),

    ))



As you can see, the action is rather short; all the complex logic would belong in your export view. This would need to deal with objects of any type, hence the business with the ContentType.




References

https://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/#ref-contrib-admin-actions


No comments:

Post a Comment