#338 closed defect (fixed)
ManyToMany fields don''t work in the generic views
Reported by: | Owned by: | Jacob | |
---|---|---|---|
Component: | Generic views | Version: | |
Severity: | normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Given a model like:
class A(meta.Model):
...
class B(meta.Model):
fields = ( meta.ManyToManyField(A) )
then when using a {{form.as}} in the template, the selection box (the list of all A's) is filled out correctly, but the list of A's related to B is not correctly filled out.
SelectMultipleField does take in a data parameter, and appears to correctly add selected="selected" to the <option>s, but there is no data for "as" in the data dict of fields. Likely this just needs to be setup properly somewhere. Don't know if/what anything special needs to be done on the POST-submission side of things.
Attachments (3)
Change History (15)
comment:1 by , 19 years ago
comment:2 by , 19 years ago
Component: | Template system → Generic views |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:3 by , 19 years ago
Does this apply to ForeignKey fields, too? I'm seeing the same behavior in generic views for a ForeignKey field of mine. The choices are populated correctly, but "data" is empty when the tag is built, so the "selected" attribute defaults to the first choice (the dashes indicating to select one choice).
comment:4 by , 19 years ago
So the quick hack-fix for this is:
In views/generic/create_update.py, in the big else statement for the request.POST check, after "new_data = object.dict", add:
for f in opts.many_to_many:
if f.rel.raw_id_admin:
new_data[f.name] = ",".join([str(i.id) for i in getattr(obj, 'get_%s_list' % f.rel.singular)()])
Basically, a c&p of the code from the admin interface to use the functions that we need in the generic views. If this is a proper fix, great, but I imagine there should be some reorganization to factor out the common "set up data for public web page viewing" functionality (dates, many2manys, etc)
comment:5 by , 19 years ago
Of course, I forgot to properly test my original (cu.diff) diff, so it doesn't quite fix many2many-in-generic-views. The most recently uploaded diff (cu.2.diff) does work, though.
by , 19 years ago
Attachment: | django-select-prepopulate.patch added |
---|
Incomplete fix that is not specific to generic views.
comment:6 by , 19 years ago
mlamberts fixes above are modifications of the generic views. This is highly suboptimal: the manipulators should not need several hacks around them in order to work, and adding these hacks to every place manipulators are used is just wrong.
So my patch changes the way form fields work : they no longer assume that every field keeps its data in a field of exactly the same name. Instead, each field can extract the data from the dictionary itself.
I have only written this for one case : select fields of foreign keys. I have not tested if this breaks the admin ( but I doubt it, it probably just makes the hacks there pointless). Other fields will need to implement either get_member_name or extract_data if they store data in a non standard way, eg date fields.
comment:7 by , 19 years ago
milestone: | → Version 1.0 |
---|
comment:8 by , 19 years ago
Cc: | added |
---|
comment:9 by , 18 years ago
Summary: | ManyToMany fields don't work in the generic views → ManyToMany fields don''t work in the generic views |
---|
Hi all
im fine, gl all!
comment:10 by , 18 years ago
Cc: | removed |
---|
comment:11 by , 18 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
I believe this has been fixed at some point in the interim. I just tried putting a many-to-many related field in a form and it was displayed as a select box with all the currently selected values shown as selected (and the other values as not selected).
Closing for now. If the problem still exists, please reopen, perhaps with a more concrete example (e.g. a form template that fails when used in the create_update generic view).
views.admin.main's change_stage does a bunch of logic for filling up new_data, including handling many_to_many objects. I imagine code like this just needs to be run for generic views as well.