我的模板上有一个表单和一个formset。问题是,formset抛出了验证错误,声称管理表单“丢失或被篡改”。
这是我的观点
@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 ))
我的模板
{%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%}
这是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
答案 0 :(得分:7)
要避免此错误,只需将您的formset POST绑定在try / except块中,就像这样。
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')
来自blogform
的POST请求缺少delblogformset
所需的'ManagementForm'隐藏输入,因此会抛出验证错误。我们包装了一个try / except块,因为我们知道如果ValidationError
已经提出,那么POST适用于blogform
而不是delblogformset
。
有关详细信息,请参阅django docs:http://docs.djangoproject.com/en/dev/topics/forms/formsets/#understanding-the-managementform
答案 1 :(得分:1)
我遇到同样的错误后想出来了。在同一视图和模板中使用表单和表单集的情况下,应在表单集之前处理表单,以避免引发表单集验证错误。
重要性另外,if request.method == 'POST':
只应该用在表单上。因此,以上内容将在视图中显示如下:
@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 ))