How can I send data to intermediate page when using custom django action?

I want to add custom django action that allows to change choice field for my model.

I want intermediate page, where user can set the new value for this field. This field should be on another URL.

The problem is that I need somehow send selected ids to this intermediate page, and GET params is not an option, because the amount of ids can be too big, and I have project restriction of url length to be strictly less then 8000 symbols.

Right now I have this setup and it works great, but I have no clue how can I send selected object ids without GET params.

forms.py

class MyModelChangeStepForm(Form):
    _selected_action = forms.CharField(widget=forms.MultipleHiddenInput)
    step_code = forms.ChoiceField(choices=...)

admin.py

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    actions = ('change_mymodel_step',)

    @admin.action(description='')
    def change_mymodel_step(self, request, queryset):
        selected_mymodel_ids = list(queryset.values_list('id', flat=True))
        mymodels_count = len(selected_mymodel_ids)
        if 'apply' in request.POST:
            form = MyModelChangeStepForm(request.POST)
            if form.is_valid():
                new_step_code = form.cleaned_data['step_code']
                # use `filter` instead of `queryset` to prevent FieldError because queryset has annotations
                MyModel.objects.filter(pk__in=selected_mymodel_ids).update(step_code=new_step_code)
                for mymodel in queryset:
                    self.log_change(request, mymodel, '...')

                self.message_user(request, '...')
                return None

            self.message_user(
                request,
                '...',
                level=messages.ERROR,
            )
            return None

        form = MyModelChangeStepForm(initial={
            '_selected_action': selected_mymodel_ids,
            'action': request.POST['action'],
        })

        return render(
            request,
            'mymodel_change_step_code.html',
            {'form': form, 'objects': queryset, 'mymodels_count': mymodels_count},
        )

mymodel_change_step_code.html

{% extends "admin/base_site.html" %}

{% block content %}
  <div id="content" class="colM">
    <h1>Title</h1>
    <form action="" method="post">{% csrf_token %}
      {{ form }}
      <h2>Stats</h2>
      <ul><li>Total: {{ mymodels_count }}</li></ul>
      <h2>Objects:</h2>
      <ul>{{ objects|unordered_list }}</ul>
      <input type="hidden" name="action" value="change_mymodel_step">
      <input type="submit" name="apply" value="Apply" class="button">
      <a href="{{ request.META.HTTP_REFERER }}">Cancel</a>
    </form>
  </div>

{% endblock %}

I heard that I can send this data using request.session, but I'm not sure that this is a correct way. I'm new to python and django, so I don't know any good practices to do this.

Вернуться на верх