The Django docs suggest sending queryset id’s for admin actions. This works until you get tens of thousands of id’s in a queryset. At this point your URL with GET variables becomes too large.
I’m working around this with sessions. It’s not quite as nice as your url is no longer copy/pastable. I decided to display such to the user.
Here’s my action to export data.
def export_simple_selected_objects(modeladmin, request, queryset):
selected_int = queryset.values_list('id', flat=True)
selected = []
for s in selected_int:
selected.append(str(s))
ct = ContentType.objects.get_for_model(queryset.model)
if len(selected) > 10000:
request.session['selected_ids'] = selected
return HttpResponseRedirect("/admin_export/export_to_xls/?ct=%s&ids=IN_SESSION" % (ct.pk,))
else:
return HttpResponseRedirect("/admin_export/export_to_xls/?ct=%s&ids=%s" % (ct.pk, ",".join(selected)))
export_simple_selected_objects.short_description = "Export selected items to XLS"
admin.site.add_action(export_simple_selected_objects)
Then in my action view
field_name = self.request.GET.get('field', '')
model_class = ContentType.objects.get(id=self.request.GET['ct']).model_class()
if self.request.GET['ids'] == "IN_SESSION":
queryset = model_class.objects.filter(pk__in=self.request.session['selected_ids'])
else:
queryset = model_class.objects.filter(pk__in=self.request.GET['ids'].split(','))
At least now the user will know the data is in the session. Note the 10,000 limit is just made up! If your users don’t know what sessions are, their action will just work instead of doing nothing 🙂