Django Formset管理表单验证错误

时间:2010-03-29 07:10:59

标签: python django django-templates django-forms

我的模板上有一个表单和一个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 

2 个答案:

答案 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 ))