#20347 closed New feature (fixed)
Add an absolute_max parameter to formset_factory
Reported by: | Carsten Fuchs | Owned by: | David Smith |
---|---|---|---|
Component: | Forms | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The documentation at https://docs.djangoproject.com/en/1.5/topics/forms/formsets/#limiting-the-maximum-number-of-forms seems to indicate (if I understood it correctly) that the purpose of the max_num
parameter is to prevent that someone sends a manipulated, excessively large value in the hidden form field that states the number of (extra) forms that are submitted, whereas it is not (directly) related to the number of forms that are actually POSTed, or initialized via parameter initials
.
However, following the example at that page, with MyInitials
being a list of e.g. 1500 initial values and request.POST
containing more than 1500 formsets:
>>> ArticleFormSet = formset_factory(ArticleForm, extra=0) >>> formset1 = ArticleFormSet(initial=MyInitials) >>> formset2 = ArticleFormSet(request.POST)
Now, accessing formset1.forms[1000]
throws an IndexError exception.
The max_num
is at its default value of 1000, but in the above context, it is not expected that formset1
or formset2
is reduced to max_num
forms -- I'd have expected each to have the full number of forms as initialized.
Related thread at django-users: http://thread.gmane.org/gmane.comp.python.django.user/152946
Change History (14)
comment:1 by , 11 years ago
Component: | Forms → Documentation |
---|---|
Easy pickings: | set |
Summary: | Creating a formset with more than max_num forms → Note that initializing a formset will be limited by max_num |
Triage Stage: | Unreviewed → Accepted |
Type: | Uncategorized → Cleanup/optimization |
comment:2 by , 11 years ago
Clarifying the documentation would certainly help, but doesn't this mean that we have to use max_num=len(MyInitials)
as a "permanent" work-around in user code?
ArticleFormSet = formset_factory(ArticleForm, max_num=len(MyInitials), extra=0)
comment:3 by , 11 years ago
(Sorry, the above comment was by me, but I realized too late that I wasn't logged in when submitting.)
comment:4 by , 11 years ago
Component: | Documentation → Forms |
---|---|
Type: | Cleanup/optimization → Bug |
Yes, this is actually a bug, and it is already fixed in master as part of the fix for #20084. absolute_max
, which unlike max_num
is a hard limit on the number of forms instantiated, in Django 1.5.1 is set to max(1000, max_num)
, which means that if max_num >= 1000
, then absolute_max == max_num
, meaning max_num
essentially becomes a hard limit (which it is not intended or documented to be).
Even with the fix for #20084, where absolute_max
is set to max_num + 1000
instead, it would still be possible for someone to hit this issue if they instantiate a formset with over 1000 more initial forms than max_num
. Given that it seems people are using formsets with higher numbers of forms than anticipated, I think we should probably go further than #20084 did and fix this fully, by documenting absolute_max
and making it explicitly configurable in formset_factory
.
The other question is whether this deserves a backport to 1.5.X. I think it probably does, given that it could be a data-loss situation.
comment:5 by , 11 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:6 by , 11 years ago
Easy pickings: | unset |
---|---|
Has patch: | set |
Patch needs improvement: | set |
Summary: | Note that initializing a formset will be limited by max_num → Add an absolute_max parameter to formset_factory |
Type: | Bug → New feature |
Pull request which has some minor comments from Carl.
comment:7 by , 5 years ago
Owner: | changed from | to
---|---|
Patch needs improvement: | unset |
comment:9 by , 4 years ago
Patch needs improvement: | set |
---|
comment:10 by , 4 years ago
Patch needs improvement: | unset |
---|
comment:11 by , 4 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
I believe the code is working as intended, accepting as a documentation clarification.