[Django] #24453: Initial values for ManyToMany form fields can't be hidden

77 views
Skip to first unread message

Django

unread,
Mar 6, 2015, 3:06:26 AM3/6/15
to django-...@googlegroups.com
#24453: Initial values for ManyToMany form fields can't be hidden
----------------------------+--------------------
Reporter: girzel | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.7
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------+--------------------
Initial values can be provided for the ManyToMany field of a ModelForm, to
be used in a ModelFormSet, but if the widget is switched to the
HiddenInput class, the (as far as I can tell correct) initial value
creates a validation error:

(Hidden field <field_name>) Enter a list of values.

Take this model:

{{{
class Work(models.Model):
authors = models.ManyToManyField(Author)

initial = dict(authors=[some_author_instance])

formset = WorkFormSet(queryset=Work.objects.none(), initial=[initial])
}}}

This is supposing one extra form in the formset. If the "authors" field
remains unhidden, the initial value works as expected. If we switch the
"authors" widget to a forms.HiddenInput, however, I get the above
validation error.

I don't think simply hiding the input should affect how the initial values
are treated. FWIW, here's an example what the hidden input looks like in
the HTML:

`<input id="id_form-1-authors" name="form-1-authors" type="hidden"
value="[37L]" />`

So presumably "[37L]" isn't getting read as a list, somewhere...

--
Ticket URL: <https://code.djangoproject.com/ticket/24453>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Mar 6, 2015, 7:33:50 PM3/6/15
to django-...@googlegroups.com
#24453: Initial values for ManyToMany form fields can't be hidden
------------------------+--------------------------------------

Reporter: girzel | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.7
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
------------------------+--------------------------------------
Changes (by collinanderson):

* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0


Comment:

Hi, I think the initial is expecting integers/long instead of instances.
When I pass in an `instance` and call as_hidden() I get multiple hidden
inputs as expected.

Though I also didn't try with a formset. How are you making it hidden?

--
Ticket URL: <https://code.djangoproject.com/ticket/24453#comment:1>

Django

unread,
Mar 6, 2015, 9:47:54 PM3/6/15
to django-...@googlegroups.com
#24453: Initial values for ManyToMany form fields can't be hidden
------------------------+--------------------------------------

Reporter: girzel | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.7
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
------------------------+--------------------------------------

Comment (by girzel):

Thanks for the response! I previously tried it with a list of pks instead
of instances, and it behaves exactly the same way (the value shows up in
the HTML as "[37L]" in both cases), with the same error. I'm constructing
a list of field names to be hidden, and putting them in a variable called
"hidden", and then:

{{{
WorkFormSet = modelformset_factory(Work,
widgets=dict([(f, forms.HiddenInput())
for f in hidden]),)
}}}

That's how I hide them. It works correctly for any field that isn't a
ManyToManyField.

Should I be hiding this field some other way?

--
Ticket URL: <https://code.djangoproject.com/ticket/24453#comment:2>

Django

unread,
Mar 6, 2015, 9:53:20 PM3/6/15
to django-...@googlegroups.com
#24453: Initial values for ManyToMany form fields can't be hidden
------------------------+--------------------------------------

Reporter: girzel | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.7
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
------------------------+--------------------------------------

Comment (by collinanderson):

Ahh... I think you want to use a MultipleHiddenInput. Cause, you know,
apparently that exists :)

https://docs.djangoproject.com/en/1.7/ref/forms/widgets/#composite-widgets

I wonder if there's a good place to document your situation so other
people don't run into the same thing. Or if it would be safe to make
HiddenInput() error when given a list.

--
Ticket URL: <https://code.djangoproject.com/ticket/24453#comment:3>

Django

unread,
Mar 7, 2015, 12:19:34 AM3/7/15
to django-...@googlegroups.com
#24453: Initial values for ManyToMany form fields can't be hidden
------------------------+--------------------------------------

Reporter: girzel | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.7
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
------------------------+--------------------------------------

Comment (by girzel):

I had no idea! It works perfectly. Consider this a documentation bug
report, then. :)

First, it might be nice to note this requirement here:

https://docs.djangoproject.com/en/1.7/ref/forms/fields/#django.forms.ModelMultipleChoiceField

And just say that, if you want to hide the input, you have to use
MultipleHiddenInput. Second, the HiddenInput widget documentation (which I
did look at) says this:

> Note that there also is a MultipleHiddenInput widget that encapsulates a
set of hidden input elements.

"A set of hidden input elements" is not at all how I was thinking of a
ManyToManyField. Perhaps something like "that is used to hide inputs that
return multiple values". Or, "that return a list of values". Or...

What would probably be nicest is to have a way to say
`fields["authors"].hidden = True`, and let Django figure it out. That
would be a much larger project, however.

Also I found this intriguing, though incomprehensible:

https://docs.djangoproject.com/en/1.7/releases/1.7.3/#database-denial-of-
service-with-modelmultiplechoicefield

Thanks very much for your help.

--
Ticket URL: <https://code.djangoproject.com/ticket/24453#comment:4>

Django

unread,
Mar 7, 2015, 12:20:05 AM3/7/15
to django-...@googlegroups.com
#24453: Initial values for ManyToMany form fields can't be hidden
------------------------+--------------------------------------
Reporter: girzel | Owner: nobody
Type: Bug | Status: closed
Component: Forms | Version: 1.7
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
------------------------+--------------------------------------
Changes (by girzel):

* status: new => closed
* resolution: => invalid


--
Ticket URL: <https://code.djangoproject.com/ticket/24453#comment:5>

Reply all
Reply to author
Forward
0 new messages