不涉及request.POST.getlist的Django admin中间页设置_selected_action的正确方法是什么?

What is the correct way to set _selected_action of Django admin's intermediate page that does not involve request.POST.getlist?

我只是在测试我的中间管理页面,然后意识到我点击了 bug 15742。以下评论似乎表明我的代码是错误的:

The problem here involves how the "queryset" is preserved from the original action handler to the code that handles POST for the intermediate page. In the referenced blog post this is done like so:

if not form:
    form = self.AddTagForm(initial={'_selected_action': request.POST.getlist(admin.ACTION_CHECKBOX_NAME)})

This code is not actually using the queryset parameter passed into the action function but rather the list of selected action checkboxes in the post data, which is only going to be the 100 checkboxes on the individual page. The action code should be using the passed queryset parameter, which does contain the full list of all items, rather than this post data. However Django's doc at the moment shows ​exactly this technique of using the POST data, and that should be fixed.

那么,不涉及request.POST.getlist的正确做法是什么?这是我的 apply_regex 现在的样子:

# apply_regex.py
from django import forms
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
from django.db import transaction
import re

class RegexForm(forms.Form):
    _selected_action = forms.CharField(widget=forms.MultipleHiddenInput)
    from_regex = forms.CharField(label='From', required=True)
    to_regex = forms.CharField(label='To', required=True)
    #flags = forms.CharField(label='Flags')

def apply_regex_global(admin, request, queryset, fieldname):
    _selected_action = request.POST.getlist(ACTION_CHECKBOX_NAME)
    form = None
    if 'apply' in request.POST:
        form = RegexForm(request.POST)
        if form.is_valid():
            with transaction.commit_manually():
                try:
                    for o in queryset:
                        old_value = getattr(o, fieldname)
                        new_value = re.sub(form.data['from_regex'],
                                           form.data['to_regex'], old_value)
                        setattr(o, fieldname, new_value)
                        o.save()
                    transaction.commit()
                finally:
                    transaction.rollback()
            admin.message_user(request, "Successfully applied a regex.")
            return HttpResponseRedirect(request.get_full_path())
    if not form:
        form = RegexForm(initial={'_selected_action': _selected_action})
    return render(request, "apply_regex.html", {
        'form': form,
        'title': 'Apply regex'}
    )

# from apply_regex import apply_regex_global
class ProductAdmin(admin.ModelAdmin):
    list_display = ('product', 'vendor', 'devicetype')
    search_fields = ['product', ]
    formfield_overrides = make_textarea_use_textinput

    actions = ['apply_regex']
    def apply_regex(self, request, queryset):
        return apply_regex_global(self, request, queryset, "product")

admin.site.register(Product, ProductAdmin)

我以前解决过这个问题。看到这个 diff。基本上从查询集中获取 id 而不是 POST 数据。

queryset.values_list('id', flat=True)