Opened 12 years ago
Closed 12 years ago
#21955 closed Bug (invalid)
Formset save_as_new=True causes "This QueryDict instance is immutable" error
| Reported by: | Robin | Owned by: | nobody |
|---|---|---|---|
| Component: | Forms | Version: | 1.6 |
| 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
Basically if you post a properly setup inline formset with save_as_new=True argument:
FormSet = inlineformset_factory(Model, SubModel) formset = FormSet(request.POST, save_as_new=True)
You will get
AttributeError at / This QueryDict instance is immutable
Some demo code below:
views.py
from django.forms.models import inlineformset_factory from django.middleware.csrf import get_token from django.http import HttpResponse from django.template.base import Template, Context from app.models import App, SubApp def home(request): FormSet = inlineformset_factory(App, SubApp) if request.method == 'POST': formset = FormSet(request.POST, save_as_new=True) else: formset = FormSet() csrf = get_token(request) t = ''' <form method="POST"> {{ formset }} <input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf }}" /> <input type="submit" /> </form> ''' c = { 'formset': formset, 'csrf': csrf, } s = Template(t).render(Context(c)) return HttpResponse(s)
models.py
from django.db import models class App(models.Model): pass class SubApp(models.Model): app = models.ForeignKey(App)
Change History (3)
comment:1 by , 12 years ago
comment:2 by , 12 years ago
Sure.
Environment:
Request Method: POST
Request URL: http://localhost:8001/
Django Version: 1.6
Python Version: 2.7.6
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware')
Template error:
In template <unknown source>, error at line 3
This QueryDict instance is immutable
1 :
2 : <form method="POST">
3 : {{ formset }}
4 : <input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf }}" />
5 : <input type="submit" />
6 : </form>
7 :
Traceback:
File "/home/robin/work/d16/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
114. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/robin/work/d16/toast/toast/views.py" in home
28. s = Template(t).render(Context(c))
File "/home/robin/work/d16/lib/python2.7/site-packages/django/template/base.py" in render
140. return self._render(context)
File "/home/robin/work/d16/lib/python2.7/site-packages/django/template/base.py" in _render
134. return self.nodelist.render(context)
File "/home/robin/work/d16/lib/python2.7/site-packages/django/template/base.py" in render
840. bit = self.render_node(node, context)
File "/home/robin/work/d16/lib/python2.7/site-packages/django/template/debug.py" in render_node
78. return node.render(context)
File "/home/robin/work/d16/lib/python2.7/site-packages/django/template/debug.py" in render
91. output = force_text(output)
File "/home/robin/work/d16/lib/python2.7/site-packages/django/utils/encoding.py" in force_text
100. s = s.__unicode__()
File "/home/robin/work/d16/lib/python2.7/site-packages/django/forms/formsets.py" in __str__
61. return self.as_table()
File "/home/robin/work/d16/lib/python2.7/site-packages/django/forms/formsets.py" in as_table
383. forms = ' '.join([form.as_table() for form in self])
File "/home/robin/work/d16/lib/python2.7/site-packages/django/forms/formsets.py" in __iter__
65. return iter(self.forms)
File "/home/robin/work/d16/lib/python2.7/site-packages/django/utils/functional.py" in __get__
49. res = instance.__dict__[self.func.__name__] = self.func(instance)
File "/home/robin/work/d16/lib/python2.7/site-packages/django/forms/formsets.py" in forms
133. forms = [self._construct_form(i) for i in xrange(self.total_form_count())]
File "/home/robin/work/d16/lib/python2.7/site-packages/django/forms/models.py" in _construct_form
843. form.data[form.add_prefix(self._pk_field.name)] = None
File "/home/robin/work/d16/lib/python2.7/site-packages/django/http/request.py" in __setitem__
318. self._assert_mutable()
File "/home/robin/work/d16/lib/python2.7/site-packages/django/http/request.py" in _assert_mutable
315. raise AttributeError("This QueryDict instance is immutable")
Exception Type: AttributeError at /
Exception Value: This QueryDict instance is immutable
comment:3 by , 12 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
I'm not sure this is legal. Django's tests pass an instance and in that case save_as_new appears to work. The docs also show an example with an instance parameter.
Anyway, since save_as_new isn't documented, you're in private API territory here. If you have a patch for this we may take a look, otherwise we're just going to say that the public API works.
Could you provide the full traceback please?