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.