Django 管理表单失败,因为“form-TOTAL_FORMS"和“form-INITIAL_FORMS"未正确填充 [英] Django Management Form is failing because 'form-TOTAL_FORMS' and 'form-INITIAL_FORMS' aren't correctly populated

查看:29
本文介绍了Django 管理表单失败,因为“form-TOTAL_FORMS"和“form-INITIAL_FORMS"未正确填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建嵌套表单,通过以下提供的示例进行最佳描述:

I would like to create nested forms as is best described through the example provided at:

http://yergler.net/blog/2009/09/27/nested-formsets-with-django/

这个页面的教程好像还不错&&它试图解决我遇到的确切问题.

The tutorial at this page seems to be pretty good && it is attempting to accomplish the exact problem I am encountering.

当没有 POST 请求数据(即我们从数据库执行初始填充)时,views.py 文件中的此实现似乎存在问题.

There seems to be an issue with this implementation in the views.py file when there is no POST request data (I.e. we are performing the initial population from database).

代码可以在上面提供的 URL 中看到(如果需要,我可以发布一些代码,但我担心它会影响这里提供的信息).

The code can be seen at the URL provided above (if needed I can post some of the code, but I fear it will take away from the information provided here).

这是失败的 views.py 代码(粗体):

Here is the views.py code that is failing (in bold):

block = get_object_or_404(models.Block, id=block_id)

if request.method == 'POST':
    formset = forms.BuildingFormset(request.POST, instance=block)

    if formset.is_valid():
        rooms = formset.save_all()

        return redirect('block_view', block_id=block.id)

else:
    formset = forms.BuildingFormset(instance=block)  #This is the line that is throwing the ValidationError 

我收到的错误信息是:

ValidationError at "urlName":
[u'ManagementForm data is missing or has been tampered with']

我进行了更深入的挖掘,看来此故障发生在 site-packages/django/forms/formsets.py 行上

I have dug deeper and it appears this failure is ocurring at line site-packages/django/forms/formsets.py

is_valid() 检查失败,因为某些 managementform 所需的数据(form-TOTAL_FORMS、form-INITIAL_FORMS 和 form-MAX_NUM_FORMS)无效.下面是 self.errors 的实际输出:

The is_valid() check is failing because some of the managementform required data (form-TOTAL_FORMS, form-INITIAL_FORMS and form-MAX_NUM_FORMS) is invalid. Here is the actual output of self.errors below:

{u'TOTAL_FORMS': [u'This field is required.'], u'INITIAL_FORMS': [u'This field is required.']}

代码:

edit_building.html:

Code:

edit_building.html:

{{buildings.management_form }}

{{ buildings.management_form }}

{% for building in building.forms %}

{% for building in buildings.forms %}

 {{ building }}

 {% if building.nested %}   
   {% for formset in building.nested %}   
     {{ formset.as_table }}   
   {% endfor %}   
 {% endif %}

{% endfor %}

{% endfor %}

views.py:

def should_delete(self, form):
    """Convenience method for determining if the form’s object will
    be deleted; cribbed from BaseModelFormSet.save_existing_objects."""

    if self.can_delete:
        raw_delete_value = form._raw_value(DELETION_FIELD_NAME)
        should_delete = form.fields[DELETION_FIELD_NAME].clean(raw_delete_value)
        return should_delete

    return False

def save_all(self, commit=True):
    """Save all formsets and along with their nested formsets."""

    # Save without committing (so self.saved_forms is populated)
    # — We need self.saved_forms so we can go back and access
    #    the nested formsets
    objects = self.save(commit=False)

    # Save each instance if commit=True
    if commit:
        for o in objects:
            o.save()

    # save many to many fields if needed
    if not commit:
        self.save_m2m()

    # save the nested formsets
    for form in set(self.initial_forms + self.saved_forms):
        if self.should_delete(form): continue

        for nested in form.nested:
            nested.save(commit=commit)

forms.py:

def should_delete(self, form):
    """Convenience method for determining if the form’s object will
    be deleted; cribbed from BaseModelFormSet.save_existing_objects."""

    if self.can_delete:
        raw_delete_value = form._raw_value(DELETION_FIELD_NAME)
        should_delete = form.fields[DELETION_FIELD_NAME].clean(raw_delete_value)
        return should_delete

    return False

def save_all(self, commit=True):
    """Save all formsets and along with their nested formsets."""

    # Save without committing (so self.saved_forms is populated)
    # — We need self.saved_forms so we can go back and access
    #    the nested formsets
    objects = self.save(commit=False)

    # Save each instance if commit=True
    if commit:
        for o in objects:
            o.save()

    # save many to many fields if needed
    if not commit:
        self.save_m2m()

    # save the nested formsets
    for form in set(self.initial_forms + self.saved_forms):
        if self.should_delete(form): continue

        for nested in form.nested:
            nested.save(commit=commit)

注意事项:

  • 我已经在 https://docs.djangoproject.com/en/dev/topics/forms/formsets/#understanding-the-managementform 并没有找到任何有用的东西来讨论 DJANGO 如何自动填充这些值

    Notes:

    • I have already looked into the django documentation at https://docs.djangoproject.com/en/dev/topics/forms/formsets/#understanding-the-managementform and did not find anything too useful that discusses how these values are automatically populated by DJANGO

      我使用的是 Django V1.5

      I am using Django V1.5

      如果没有 POST 数据并且表单仅从数据库生成,'form-TOTAL_FORMS' 应该如何处理&&'form-INITIAL_FORMS'数据填写正确解决这个失败?

      In the event that there is no POST data and the form is being generated solely from the database, how should the 'form-TOTAL_FORMS' && 'form-INITIAL_FORMS' data be correctly filled in to solve this failure?

      推荐答案

      更新:

      在查看您提供的示例之后在 add_fields() 方法末尾的 forms.py 中有一段代码如下:

      After looking through the example you provided there's a snippet that reads like this in forms.py at the end of the add_fields() method:

      # store the formset in the .nested property
      form.nested = [
          TenantFormset(data = self.data,
                        instance = instance,
                        prefix = 'TENANTS_%s' % pk_value)
      ]
      

      data 参数导致问题,因为它最初是空的,并且在内部 Django 将确定表单是否 受与此类似的条件约束:

      The data argument is causing problems because it's initially empty and internally Django will determine whether or not a form is bound by a conditional that's similar to this:

      self.is_bound = data is not None
      
      # Example
      >>> my_data = {}
      >>> my_data is not None
      True
      

      正如您所看到的,Python 中的空字典不是 None,因此您的 TenantFormset 被视为 bound 表单,即使它不是.您可以使用以下内容修复它:

      And as you can see an empty dictionary in Python isn't None, so your TenantFormset is treated as a bound form even though it isn't. You could fix it with something like the following:

      # store the formset in the .nested property
      form.nested = [
          TenantFormset(data = self.data if any(self.data) else None,
                        instance = instance,
                        prefix = 'TENANTS_%s' % pk_value)
      ]
      

      <小时>

      您能否发布视图和表单代码以及表单的模板代码?


      Could you post the view and form code as well as the template code for your form?

      我的猜测是您没有在模板中使用management_form"(它添加了您缺少的form-TOTAL_FORMS"和form-INITIAL_FORMS"字段),即

      My guess is that you're not using the ‘management_form’ in your template (which adds the "form-TOTAL_FORMS" and "form-INITIAL_FORMS" fields that you're missing), i.e.

      <form method="post">
          {{ formset.management_form }}
          <table>
              {% for form in formset %}
              {{ form }}
              {% endfor %}
          </table>
      </form>
      

      这篇关于Django 管理表单失败,因为“form-TOTAL_FORMS"和“form-INITIAL_FORMS"未正确填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆