Opened 19 years ago
Closed 18 years ago
#3922 closed (fixed)
formfield_callback in form_for_model also changes refering model
| Reported by: | Owned by: | Philippe Raoult | |
|---|---|---|---|
| Component: | Forms | Version: | dev |
| Severity: | Keywords: | form_for_model | |
| Cc: | gandalf@…, cgrady@… | Triage Stage: | Accepted |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Using formfield_callback with newforms form.form_for_model will also change the model you are refering to.
def CategoryCallback(f, **kwargs):
if not "cat_" in f.name:
f.name = 'cat_'+f.name
return f.formfield(**kwargs)
>>> w = Writer(name='Bob Woodward')
>>> Article(headline='Test article', pub_date=datetime.date(1988, 1, 4), writer=w, article='Hello.')
<Article: Test article>
>>> ArticleForm = form_for_model(Article, formfield_callback=CategoryCallback)
>>> f = ArticleForm(auto_id=False)
>>> print f
<tr><th>Headline:</th><td><input type="text" name="cat_headline" maxlength="50" /></td></tr>
<tr><th>Pub date:</th><td><input type="text" name="cat_pub_date" /></td></tr>
<tr><th>Writer:</th><td><select name="cat_writer">
<option value="" selected="selected">---------</option>
</select></td></tr>
<tr><th>Article:</th><td><textarea name="cat_article"></textarea></td></tr>
<tr><th>Categories:</th><td><select multiple="multiple" name="cat_categories">
</select><br /> Hold down "Control", or "Command" on a Mac, to select more than one.</td></tr>
>>> w = Writer(name='Bob Woodward')
but then doing this one (same one as in the beginning):
>>> Article(headline='Test article', pub_date=datetime.date(1988, 1, 4), writer=w, article='Hello.')
fails with:
Traceback (most recent call last):
File "/Users/gandalf/django/django_src/django/test/doctest.py", line 1243, in __run
compileflags, 1) in test.globs
File "<doctest modeltests.model_forms_callback.models.__test__.API_TESTS[16]>", line 1, in ?
Article(headline='Test article', pub_date=datetime.date(1988, 1, 4), writer=w, article='Hello.')
File "/Users/gandalf/django/django_src/django/db/models/base.py", line 166, in __init__
raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
TypeError: 'writer' is an invalid keyword argument for this function
I have attached more comprehensive test derived from modeltests/model_form. I belive that form_for_model with callback should not affect the actual model. It is also not clear if by doing my approach .save() should still work normally or is up to the developer to rename fields back to the way they were originally defined.
Attachments (2)
Change History (7)
by , 19 years ago
comment:1 by , 19 years ago
| Cc: | added |
|---|
Doesn't the prefix argument to a Form do the same thing, but without the side-effects? :)
Editing the model fields to produce changes in the form output seems a bit backwards - perhaps a custom base form with init overrided would be better than trying to do certain modifications in the callback?
comment:2 by , 19 years ago
Yes, it probably would. But using it in this "wrong" way still shouldn't break the model in a running project.
comment:3 by , 18 years ago
There are no object/class permissions in python, there is no way to "fix" this. The documentation should mention that the argument passed to the callback is the actual class field and should not be treated as a temporary variable you can modify.
comment:4 by , 18 years ago
| Has patch: | set |
|---|---|
| Keywords: | form_for_model added; for_for_model removed |
| Owner: | changed from to |
| Status: | new → assigned |
| Triage Stage: | Unreviewed → Accepted |
comment:5 by , 18 years ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
Test for described formfield_callback problem