Django Formset management-form validation error
Solution 1
To avoid this error just wrap your formset POST bounding in a try/except block like so.
from django.core.exceptions import ValidationError # add this to your imports
if request.method == 'POST':
try:
delblogformset = delblog(request.POST)
except ValidationError:
delblogformset = None
if delblogformset and delblogformset.is_valid():
delblogformset.save()
return HttpResponseRedirect('/home')
The POST request from your blogform
lacks the 'ManagementForm' hidden input that is required for your delblogformset
and hence the validation error is thrown. We wrap in a try/except block because we know that if ValidationError
has been raised than the POST was meant for your blogform
and not delblogformset
.
For more information see django docs: http://docs.djangoproject.com/en/dev/topics/forms/formsets/#understanding-the-managementform
Solution 2
I have figured this out after running into the same error. In situations where you are using a form and a formset in the same view and template, the form should be processed before the formset to avoid raising a formset validation error.
of importance Also, if request.method == 'POST':
SHOULD ONLY be used on the formset. So the above will appear as below in the view:
@login_required
def home(request):
user = UserProfile.objects.get(pk=request.session['_auth_user_id'])
blogz = list(blog.objects.filter(deleted='0'))
delblog = modelformset_factory(blog, exclude=('poster','date' ,'title','content'))
if request.user.is_staff== True:
staff = 1
else:
staff = 0
staffis = 1
blogform = BlogForm(request.POST)
if blogform.is_valid():
blogform.save()
return HttpResponseRedirect('/home')
else:
blogform = BlogForm(initial = {'poster':user.id})
if request.method == 'POST':
delblogformset = delblog(request.POST)
if delblogformset.is_valid():
delblogformset.save()
return HttpResponseRedirect('/home')
else:
delblogformset = delblog(queryset=blog.objects.filter( deleted='0'))
blogs= zip(blogz,delblogformset.forms)
paginator = Paginator(blogs, 10) # Show 25 contacts per page
# Make sure page request is an int. If not, deliver first page.
try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1
# If page request (9999) is out of range, deliver last page of results.
try:
blogs = paginator.page(page)
except (EmptyPage, InvalidPage):
blogs = paginator.page(paginator.num_pages)
return render_to_response('home.html', {'user':user, 'blogform':blogform, 'staff': staff, 'staffis': staffis, 'blog':blogs, 'delblog':delblogformset}, context_instance = RequestContext( request ))
Dennis Kioko
Updated on July 20, 2022Comments
-
Dennis Kioko almost 2 years
I have a form and a formset on my template. The problem is that the formset is throwing validation error claiming that the management form is "missing or has been tampered with".
Here is my view
@login_required def home(request): user = UserProfile.objects.get(pk=request.session['_auth_user_id']) blogz = list(blog.objects.filter(deleted='0')) delblog = modelformset_factory(blog, exclude=('poster','date' ,'title','content')) if request.user.is_staff== True: staff = 1 else: staff = 0 staffis = 1 if request.method == 'POST': delblogformset = delblog(request.POST) if delblogformset.is_valid(): delblogformset.save() return HttpResponseRedirect('/home') else: delblogformset = delblog(queryset=blog.objects.filter( deleted='0')) blogform = BlogForm(request.POST) if blogform.is_valid(): blogform.save() return HttpResponseRedirect('/home') else: blogform = BlogForm(initial = {'poster':user.id}) blogs= zip(blogz,delblogformset.forms) paginator = Paginator(blogs, 10) # Show 25 contacts per page # Make sure page request is an int. If not, deliver first page. try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 # If page request (9999) is out of range, deliver last page of results. try: blogs = paginator.page(page) except (EmptyPage, InvalidPage): blogs = paginator.page(paginator.num_pages) return render_to_response('home.html', {'user':user, 'blogform':blogform, 'staff': staff, 'staffis': staffis, 'blog':blogs, 'delblog':delblogformset}, context_instance = RequestContext( request ))
my template
{%block content%} <h2>Home</h2> {% ifequal staff staffis %} {% if form.errors %} <ul> {% for field in form %} <H3 class="title"> <p class="error"> {% if field.errors %}<li>{{ field.errors|striptags }}</li>{% endif %}</p> </H3> {% endfor %} </ul> {% endif %} <h3>Post a Blog to the Front Page</h3> <form method="post" id="form2" action="" class="infotabs accfrm"> {{ blogform.as_p }} <input type="submit" value="Submit" /> </form> <br> <br> {% endifequal %} <div class="pagination"> <span class="step-links"> {% if blog.has_previous %} <a href="?page={{ blog.previous_page_number }}">previous</a> {% endif %} <span class="current"> Page {{ blog.number }} of {{ blog.paginator.num_pages }}. </span> {% if blog.has_next %} <a href="?page={{ blog.next_page_number }}">next</a> {% endif %} </span> <form method="post" action="" class="usertabs accfrm"> {{delblog.management_form}} {% for b, form in blog.object_list %} <div class="blog"> <h3>{{b.title}}</h3> <p>{{b.content}}</p> <p>posted by <strong>{{b.poster}}</strong> on {{b.date}}</p> {% ifequal staff staffis %}<p>{{form.as_p}}<input type="submit" value="Delete" /></p>{% endifequal %} </div> {% endfor %} </form> {%endblock%}
Here is the Traceback
ValidationError at /home/ Request Method: POST Request URL: http://localhost:8000/home/ Exception Type: ValidationError Exception Value: Exception Location: /usr/lib/python2.6/site-packages/django/forms/formsets.py in _management_form, line 54 Python Executable: /usr/bin/python Python Version: 2.6.2 Python Path: ['/home/projects/acms', '/usr/lib/python2.6/site-packages/django_socialregistration-0.2-py2.6.egg', '/usr/lib/python26.zip', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old', '/usr/lib/python2.6/lib-dynload', '/usr/lib/python2.6/site-packages', '/usr/lib/python2.6/site-packages/Numeric', '/usr/lib/python2.6/site-packages/PIL', '/usr/lib/python2.6/site-packages/gst-0.10', '/usr/lib/python2.6/site-packages/gtk-2.0', '/usr/lib/python2.6/site-packages/webkit-1.0'] Server time: Mon, 29 Mar 2010 12:02:43 +0300 Traceback Switch to copy-and-paste view * /usr/lib/python2.6/site-packages/django/core/handlers/base.py in get_response 85. # Apply view middleware 86. for middleware_method in self._view_middleware: 87. response = middleware_method(request, callback, callback_args, callback_kwargs) 88. if response: 89. return response 90. 91. try: 92. response = callback(request, *callback_args, **callback_kwargs) ... 93. except Exception, e: 94. # If the view raised an exception, run it through exception 95. # middleware, and if the exception middleware returns a 96. # response, use that. Otherwise, reraise the exception. 97. for middleware_method in self._exception_middleware: 98. response = middleware_method(request, e) ▶ Local vars Variable Value callback <django.contrib.auth.decorators._CheckLogin object at 0xb655ad2c> callback_args () callback_kwargs {} e ValidationError() exc_info (<class 'django.forms.util.ValidationError'>, ValidationError(), <traceback object at 0xb6630a2c>) exceptions <module 'django.core.exceptions' from '/usr/lib/python2.6/site-packages/django/core/exceptions.pyc'> middleware_method <bound method TransactionMiddleware.process_exception of <django.middleware.transaction.TransactionMiddleware object at 0xb676ff6c>> receivers [(<function _rollback_on_exception at 0x8c845dc>, None)] request <WSGIRequest GET:<QueryDict: {}>, POST:<QueryDict: {u'content': [u'test'], u'poster': [u'4'], u'title': [u'test']}>, COOKIES:{'sessionid': '8f4b4fa8411cc5baa05c2016a8ad00f4'}, META:{'COLORTERM': 'gnome-terminal', 'CONTENT_LENGTH': '32', 'CONTENT_TYPE': 'application/x-www-form-urlencoded', 'CVS_RSH': 'ssh', 'DBUS_SESSION_BUS_ADDRESS': 'unix:abstract=/tmp/dbus-nKl1u8UWGs,guid=fabac1ba0d651ceae76e1d9a4bafa535', 'DESKTOP_SESSION': 'gnome', 'DISPLAY': ':0.0', 'DJANGO_SETTINGS_MODULE': 'acms.settings', 'GATEWAY_INTERFACE': 'CGI/1.1', 'GDMSESSION': 'gnome', 'GDM_KEYBOARD_LAYOUT': 'us', 'GDM_LANG': 'en_GB.UTF-8', 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated', 'GNOME_KEYRING_PID': '1511', 'GNOME_KEYRING_SOCKET': '/tmp/keyring-uvdktc/socket', 'GTK_RC_FILES': '/etc/gtk/gtkrc:/home/user/.gtkrc-1.2-gnome2', 'G_BROKEN_FILENAMES': '1', 'HISTCONTROL': 'ignoreboth', 'HISTSIZE': '1000', 'HOME': '/home/user', 'HOSTNAME': 'desktop.theblackout', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'HTTP_ACCEPT_CHARSET': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'HTTP_ACCEPT_ENCODING': 'gzip,deflate', 'HTTP_ACCEPT_LANGUAGE': 'en-us,en;q=0.5', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_COOKIE': 'sessionid=8f4b4fa8411cc5baa05c2016a8ad00f4', 'HTTP_HOST': 'localhost:8000', 'HTTP_KEEP_ALIVE': '115', 'HTTP_REFERER': 'http://localhost:8000/home/', 'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2) Gecko/20100218 Fedora/3.6.1-1.fc13 Firefox/3.6', 'IMSETTINGS_INTEGRATE_DESKTOP': 'yes', 'IMSETTINGS_MODULE': 'none', 'KDEDIRS': '/usr', 'KDE_IS_PRELINKED': '1', 'KMIX_PULSEAUDIO_DISABLE': '1', 'LANG': 'en_GB.UTF-8', 'LESSOPEN': '|/usr/bin/lesspipe.sh %s', 'LOGNAME': 'user', 'LS_COLORS': 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:', 'MAIL': '/var/spool/mail/user', 'OLDPWD': '/home/user', 'ORBIT_SOCKETDIR': '/tmp/orbit-user', 'PATH': '/usr/lib/qt-3.3/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/lib/ccache:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/real/RealPlayer:/home/user/bin:/opt/real/RealPlayer', 'PATH_INFO': u'/home/', 'PWD': '/home/projects/acms', 'QTDIR': '/usr/lib/qt-3.3', 'QTINC': '/usr/lib/qt-3.3/include', 'QTLIB': '/usr/lib/qt-3.3/lib', 'QT_IM_MODULE': 'xim', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_HOST': '', 'REQUEST_METHOD': 'POST', 'RUN_MAIN': 'true', 'SCRIPT_NAME': u'', 'SERVER_NAME': 'localhost.localdomain', 'SERVER_PORT': '8000', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'WSGIServer/0.1 Python/2.6.2', 'SESSION_MANAGER': 'local/unix:@/tmp/.ICE-unix/1518,unix/unix:/tmp/.ICE-unix/1518', 'SHELL': '/bin/bash', 'SHLVL': '2', 'SSH_ASKPASS': '/usr/libexec/openssh/gnome-ssh-askpass', 'SSH_AUTH_SOCK': '/tmp/keyring-uvdktc/socket.ssh', 'TERM': 'xterm', 'TZ': 'Africa/Nairobi', 'USER': 'user', 'USERNAME': 'user', 'WINDOWID': '79691779', 'XAUTHORITY': '/var/run/gdm/auth-for-user-YHprr5/database', 'XDG_SESSION_COOKIE': 'b52f8ef12c1cf7be85729e5e4ae08729-1269802292.411279-1821712829', 'XMODIFIERS': '@im=none', '_': '/usr/bin/python', 'wsgi.errors': <open file '<stderr>', mode 'w' at 0xb76b70c0>, 'wsgi.file_wrapper': <class 'django.core.servers.basehttp.FileWrapper'>, 'wsgi.input': <socket._fileobject object at 0xb675f8b4>, 'wsgi.multiprocess': False, 'wsgi.multithread': True, 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.version': (1, 0)}> resolver <RegexURLResolver acms.urls (None:None) ^/> response None self <django.core.handlers.wsgi.WSGIHandler object at 0xb6755acc> settings <django.conf.LazySettings object at 0xb740856c> urlconf 'acms.urls' urlresolvers <module 'django.core.urlresolvers' from '/usr/lib/python2.6/site-packages/django/core/urlresolvers.pyc'> * /usr/lib/python2.6/site-packages/django/contrib/auth/decorators.py in __call__ 71. 72. def __get__(self, obj, cls=None): 73. view_func = self.view_func.__get__(obj, cls) 74. return _CheckLogin(view_func, self.test_func, self.login_url, self.redirect_field_name) 75. 76. def __call__(self, request, *args, **kwargs): 77. if self.test_func(request.user): 78. return self.view_func(request, *args, **kwargs) ... 79. path = urlquote(request.get_full_path()) 80. tup = self.login_url, self.redirect_field_name, path 81. return HttpResponseRedirect('%s?%s=%s' % tup) ▶ Local vars Variable Value args () kwargs {} request <WSGIRequest GET:<QueryDict: {}>, POST:<QueryDict: {u'content': [u'test'], u'poster': [u'4'], u'title': [u'test']}>, COOKIES:{'sessionid': '8f4b4fa8411cc5baa05c2016a8ad00f4'}, META:{'COLORTERM': 'gnome-terminal', 'CONTENT_LENGTH': '32', 'CONTENT_TYPE': 'application/x-www-form-urlencoded', 'CVS_RSH': 'ssh', 'DBUS_SESSION_BUS_ADDRESS': 'unix:abstract=/tmp/dbus-nKl1u8UWGs,guid=fabac1ba0d651ceae76e1d9a4bafa535', 'DESKTOP_SESSION': 'gnome', 'DISPLAY': ':0.0', 'DJANGO_SETTINGS_MODULE': 'acms.settings', 'GATEWAY_INTERFACE': 'CGI/1.1', 'GDMSESSION': 'gnome', 'GDM_KEYBOARD_LAYOUT': 'us', 'GDM_LANG': 'en_GB.UTF-8', 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated', 'GNOME_KEYRING_PID': '1511', 'GNOME_KEYRING_SOCKET': '/tmp/keyring-uvdktc/socket', 'GTK_RC_FILES': '/etc/gtk/gtkrc:/home/user/.gtkrc-1.2-gnome2', 'G_BROKEN_FILENAMES': '1', 'HISTCONTROL': 'ignoreboth', 'HISTSIZE': '1000', 'HOME': '/home/user', 'HOSTNAME': 'desktop.theblackout', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'HTTP_ACCEPT_CHARSET': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'HTTP_ACCEPT_ENCODING': 'gzip,deflate', 'HTTP_ACCEPT_LANGUAGE': 'en-us,en;q=0.5', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_COOKIE': 'sessionid=8f4b4fa8411cc5baa05c2016a8ad00f4', 'HTTP_HOST': 'localhost:8000', 'HTTP_KEEP_ALIVE': '115', 'HTTP_REFERER': 'http://localhost:8000/home/', 'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2) Gecko/20100218 Fedora/3.6.1-1.fc13 Firefox/3.6', 'IMSETTINGS_INTEGRATE_DESKTOP': 'yes', 'IMSETTINGS_MODULE': 'none', 'KDEDIRS': '/usr', 'KDE_IS_PRELINKED': '1', 'KMIX_PULSEAUDIO_DISABLE': '1', 'LANG': 'en_GB.UTF-8', 'LESSOPEN': '|/usr/bin/lesspipe.sh %s', 'LOGNAME': 'user', 'LS_COLORS': 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:', 'MAIL': '/var/spool/mail/user', 'OLDPWD': '/home/user', 'ORBIT_SOCKETDIR': '/tmp/orbit-user', 'PATH': '/usr/lib/qt-3.3/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/lib/ccache:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/real/RealPlayer:/home/user/bin:/opt/real/RealPlayer', 'PATH_INFO': u'/home/', 'PWD': '/home/projects/acms', 'QTDIR': '/usr/lib/qt-3.3', 'QTINC': '/usr/lib/qt-3.3/include', 'QTLIB': '/usr/lib/qt-3.3/lib', 'QT_IM_MODULE': 'xim', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_HOST': '', 'REQUEST_METHOD': 'POST', 'RUN_MAIN': 'true', 'SCRIPT_NAME': u'', 'SERVER_NAME': 'localhost.localdomain', 'SERVER_PORT': '8000', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'WSGIServer/0.1 Python/2.6.2', 'SESSION_MANAGER': 'local/unix:@/tmp/.ICE-unix/1518,unix/unix:/tmp/.ICE-unix/1518', 'SHELL': '/bin/bash', 'SHLVL': '2', 'SSH_ASKPASS': '/usr/libexec/openssh/gnome-ssh-askpass', 'SSH_AUTH_SOCK': '/tmp/keyring-uvdktc/socket.ssh', 'TERM': 'xterm', 'TZ': 'Africa/Nairobi', 'USER': 'user', 'USERNAME': 'user', 'WINDOWID': '79691779', 'XAUTHORITY': '/var/run/gdm/auth-for-user-YHprr5/database', 'XDG_SESSION_COOKIE': 'b52f8ef12c1cf7be85729e5e4ae08729-1269802292.411279-1821712829', 'XMODIFIERS': '@im=none', '_': '/usr/bin/python', 'wsgi.errors': <open file '<stderr>', mode 'w' at 0xb76b70c0>, 'wsgi.file_wrapper': <class 'django.core.servers.basehttp.FileWrapper'>, 'wsgi.input': <socket._fileobject object at 0xb675f8b4>, 'wsgi.multiprocess': False, 'wsgi.multithread': True, 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.version': (1, 0)}> self <django.contrib.auth.decorators._CheckLogin object at 0xb655ad2c> * /home/projects/acms/../acms/cms/views.py in home 45. if request.user.is_staff== True: 46. staff = 1 47. else: 48. staff = 0 49. staffis = 1 50. 51. if request.method == 'POST': 52. delblogformset = delblog(request.POST) ... 53. if delblogformset.is_valid(): 54. delblogformset.save() 55. return HttpResponseRedirect('/home') 56. 57. else: 58. delblogformset = delblog(queryset=blog.objects.filter( deleted='0')) ▶ Local vars Variable Value blogz Error in formatting: %d format: a number is required, not unicode delblog <class 'django.forms.formsets.blogFormFormSet'> request <WSGIRequest GET:<QueryDict: {}>, POST:<QueryDict: {u'content': [u'test'], u'poster': [u'4'], u'title': [u'test']}>, COOKIES:{'sessionid': '8f4b4fa8411cc5baa05c2016a8ad00f4'}, META:{'COLORTERM': 'gnome-terminal', 'CONTENT_LENGTH': '32', 'CONTENT_TYPE': 'application/x-www-form-urlencoded', 'CVS_RSH': 'ssh', 'DBUS_SESSION_BUS_ADDRESS': 'unix:abstract=/tmp/dbus-nKl1u8UWGs,guid=fabac1ba0d651ceae76e1d9a4bafa535', 'DESKTOP_SESSION': 'gnome', 'DISPLAY': ':0.0', 'DJANGO_SETTINGS_MODULE': 'acms.settings', 'GATEWAY_INTERFACE': 'CGI/1.1', 'GDMSESSION': 'gnome', 'GDM_KEYBOARD_LAYOUT': 'us', 'GDM_LANG': 'en_GB.UTF-8', 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated', 'GNOME_KEYRING_PID': '1511', 'GNOME_KEYRING_SOCKET': '/tmp/keyring-uvdktc/socket', 'GTK_RC_FILES': '/etc/gtk/gtkrc:/home/user/.gtkrc-1.2-gnome2', 'G_BROKEN_FILENAMES': '1', 'HISTCONTROL': 'ignoreboth', 'HISTSIZE': '1000', 'HOME': '/home/user', 'HOSTNAME': 'desktop.theblackout', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'HTTP_ACCEPT_CHARSET': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'HTTP_ACCEPT_ENCODING': 'gzip,deflate', 'HTTP_ACCEPT_LANGUAGE': 'en-us,en;q=0.5', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_COOKIE': 'sessionid=8f4b4fa8411cc5baa05c2016a8ad00f4', 'HTTP_HOST': 'localhost:8000', 'HTTP_KEEP_ALIVE': '115', 'HTTP_REFERER': 'http://localhost:8000/home/', 'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2) Gecko/20100218 Fedora/3.6.1-1.fc13 Firefox/3.6', 'IMSETTINGS_INTEGRATE_DESKTOP': 'yes', 'IMSETTINGS_MODULE': 'none', 'KDEDIRS': '/usr', 'KDE_IS_PRELINKED': '1', 'KMIX_PULSEAUDIO_DISABLE': '1', 'LANG': 'en_GB.UTF-8', 'LESSOPEN': '|/usr/bin/lesspipe.sh %s', 'LOGNAME': 'user', 'LS_COLORS': 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:', 'MAIL': '/var/spool/mail/user', 'OLDPWD': '/home/user', 'ORBIT_SOCKETDIR': '/tmp/orbit-user', 'PATH': '/usr/lib/qt-3.3/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/lib/ccache:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/real/RealPlayer:/home/user/bin:/opt/real/RealPlayer', 'PATH_INFO': u'/home/', 'PWD': '/home/projects/acms', 'QTDIR': '/usr/lib/qt-3.3', 'QTINC': '/usr/lib/qt-3.3/include', 'QTLIB': '/usr/lib/qt-3.3/lib', 'QT_IM_MODULE': 'xim', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_HOST': '', 'REQUEST_METHOD': 'POST', 'RUN_MAIN': 'true', 'SCRIPT_NAME': u'', 'SERVER_NAME': 'localhost.localdomain', 'SERVER_PORT': '8000', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'WSGIServer/0.1 Python/2.6.2', 'SESSION_MANAGER': 'local/unix:@/tmp/.ICE-unix/1518,unix/unix:/tmp/.ICE-unix/1518', 'SHELL': '/bin/bash', 'SHLVL': '2', 'SSH_ASKPASS': '/usr/libexec/openssh/gnome-ssh-askpass', 'SSH_AUTH_SOCK': '/tmp/keyring-uvdktc/socket.ssh', 'TERM': 'xterm', 'TZ': 'Africa/Nairobi', 'USER': 'user', 'USERNAME': 'user', 'WINDOWID': '79691779', 'XAUTHORITY': '/var/run/gdm/auth-for-user-YHprr5/database', 'XDG_SESSION_COOKIE': 'b52f8ef12c1cf7be85729e5e4ae08729-1269802292.411279-1821712829', 'XMODIFIERS': '@im=none', '_': '/usr/bin/python', 'wsgi.errors': <open file '<stderr>', mode 'w' at 0xb76b70c0>, 'wsgi.file_wrapper': <class 'django.core.servers.basehttp.FileWrapper'>, 'wsgi.input': <socket._fileobject object at 0xb675f8b4>, 'wsgi.multiprocess': False, 'wsgi.multithread': True, 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.version': (1, 0)}> staff 1 staffis 1 user <UserProfile: Treasurer> * /usr/lib/python2.6/site-packages/django/forms/models.py in __init__ 452. model = None 453. 454. def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, 455. queryset=None, **kwargs): 456. self.queryset = queryset 457. defaults = {'data': data, 'files': files, 'auto_id': auto_id, 'prefix': prefix} 458. defaults.update(kwargs) 459. super(BaseModelFormSet, self).__init__(**defaults) ... 460. 461. def initial_form_count(self): 462. """Returns the number of forms that are required in this FormSet.""" 463. if not (self.data or self.files): 464. return len(self.get_queryset()) 465. return super(BaseModelFormSet, self).initial_form_count() ▶ Local vars Variable Value auto_id 'id_%s' data <QueryDict: {u'content': [u'test'], u'poster': [u'4'], u'title': [u'test']}> defaults {'auto_id': 'id_%s', 'data': <QueryDict: {u'content': [u'test'], u'poster': [u'4'], u'title': [u'test']}>, 'files': None, 'prefix': None} files None kwargs {} prefix None queryset None self <django.forms.formsets.blogFormFormSet object at 0xb659bdec> * /usr/lib/python2.6/site-packages/django/forms/formsets.py in __init__ 37. self.data = data 38. self.files = files 39. self.initial = initial 40. self.error_class = error_class 41. self._errors = None 42. self._non_form_errors = None 43. # construct the forms in the formset 44. self._construct_forms() ... 45. 46. def __unicode__(self): 47. return self.as_table() 48. 49. def _management_form(self): 50. """Returns the ManagementForm instance for this FormSet.""" ▶ Local vars Variable Value auto_id 'id_%s' data <QueryDict: {u'content': [u'test'], u'poster': [u'4'], u'title': [u'test']}> error_class <class 'django.forms.util.ErrorList'> files None initial None prefix None self <django.forms.formsets.blogFormFormSet object at 0xb659bdec> * /usr/lib/python2.6/site-packages/django/forms/formsets.py in _construct_forms 80. if initial_forms > self.max_num > 0: 81. initial_forms = self.max_num 82. return initial_forms 83. 84. def _construct_forms(self): 85. # instantiate all the forms and put them in self.forms 86. self.forms = [] 87. for i in xrange(self.total_form_count()): ... 88. self.forms.append(self._construct_form(i)) 89. 90. def _construct_form(self, i, **kwargs): 91. """ 92. Instantiates and returns the i-th form instance in a formset. 93. """ ▶ Local vars Variable Value self <django.forms.formsets.blogFormFormSet object at 0xb659bdec> * /usr/lib/python2.6/site-packages/django/forms/formsets.py in total_form_count 59. }) 60. return form 61. management_form = property(_management_form) 62. 63. def total_form_count(self): 64. """Returns the total number of forms in this FormSet.""" 65. if self.data or self.files: 66. return self.management_form.cleaned_data[TOTAL_FORM_COUNT] ... 67. else: 68. total_forms = self.initial_form_count() + self.extra 69. if total_forms > self.max_num > 0: 70. total_forms = self.max_num 71. return total_forms 72. ▶ Local vars Variable Value self <django.forms.formsets.blogFormFormSet object at 0xb659bdec> * /usr/lib/python2.6/site-packages/django/forms/formsets.py in _management_form 47. return self.as_table() 48. 49. def _management_form(self): 50. """Returns the ManagementForm instance for this FormSet.""" 51. if self.data or self.files: 52. form = ManagementForm(self.data, auto_id=self.auto_id, prefix=self.prefix) 53. if not form.is_valid(): 54. raise ValidationError('ManagementForm data is missing or has been tampered with') ... 55. else: 56. form = ManagementForm(auto_id=self.auto_id, prefix=self.prefix, initial={ 57. TOTAL_FORM_COUNT: self.total_form_count(), 58. INITIAL_FORM_COUNT: self.initial_form_count() 59. }) 60. return form ▶ Local vars
-
akaihola about 14 yearsIf I read the mixed up indentation correctly, changes to the formset
delblogformset
are only saved when theblogform
form is invalid. If it's valid instead, the user is redirected back and all changes to the formset are lost. Also, could you explain why it is important to handle the form before the formset? Is this the same problem as described in groups.google.com/group/django-users/browse_thread/thread/… ? -
Dennis Kioko about 14 yearsi think i sorted out the indentation now, and yeah, its the same error.
-
Asotos about 9 yearsThis answer has been very helpful. In my case however the problem seemed to be that I didn't render the ManagementForm data in the template (by including something like
{{ my_formset.management_form }}
).