Django:我不能在 Formset 中添加多行而不会出错

Django : I can't add more than one row in a Formset without getting an error

我刚刚在处理我的 Django 项目时发现一个错误。总结一下这个问题,每次我尝试向表单集添加多行时,我都会收到 MultiValueDictKeyError 错误。

每次我尝试提交表单时,错误仍然存​​在,即使我没有更改表单集也是如此。

这是我的代码:View.py

def profile(request):
    # Get the user's profile
    try:
        profile = Profile.objects.get(user = request.user.id)
    except:
        profile = Profile()
        profile.user = request.user

    # inline formset for profile's pony
    PonyFormset = inlineformset_factory(Profile, Pony, fields=('pony','message',), extra = 2)

    # inline formset for profile's url
    UrlFormset = inlineformset_factory(Profile, Url, fields=('url',), extra = 2)

    if request.method == 'POST':

        form = ProfileForm(request.POST, request.FILES, instance = profile)
        ponies = PonyFormset(request.POST, instance = profile, prefix = "pony")
        urls = UrlFormset(request.POST, instance = profile, prefix = "url")

        if form.is_valid():
            form.save()
            form = ProfileForm(instance = profile)

        if ponies.is_valid():
            ponies.save()
            ponies = PonyFormset(instance = profile, prefix = "pony")

        if urls.is_valid():
            urls.save()
            urls = UrlFormset(instance = profile, prefix = "url")

    else:
        form = ProfileForm(instance = profile)
        ponies = PonyFormset(instance = profile, prefix = "pony")
        urls = UrlFormset(instance = profile, prefix = "url")

    return render(request, 'profile.html', {
        'profile': profile,
        'form':    form,
        'ponies':  ponies,
        'urls':    urls,
    })

Model.py

class Pony(models.Model):
    ''' List of ponies with little quotes to display in the user's description '''

    profile = models.ForeignKey(Profile)
    pony    = models.CharField(max_length = 32)
    message = models.CharField(max_length = 64)

    def __str__(self):
        try:
            return self.message % self.pony
        except TypeError:
            return self.message

    class Meta:
        verbose_name_plural = "ponies"

class Url(models.Model):
    ''' List of urls in the user's description '''

    profile = models.ForeignKey(Profile)
    url     = models.URLField()
    icon    = models.CharField(max_length = 16)

    def __str__(self):
        return self.url

模板

<h3>{% trans 'Url :' %}</h3>
                <!-- url -->
                {{ urls.management_form }}
                {% for urlform in urls %}
                    {% if ponies.can_delete %}
                        {% bootstrap_field urlform.url show_label=false field_class='col-xs-11' form_group_class='' %}
                        {% bootstrap_field urlform.DELETE %}
                    {% else %}
                        {% bootstrap_field urlform.message show_label=false field_class='col-xs-12' %}
                    {% endif %}
                {% endfor %}

(我只放了Url formset因为Pony formset是一样的)

和错误(超过一个url)

环境:

Request Method: POST
Request URL: http://127.0.0.1:8000/fr/profil

Django Version: 1.8.1
Python Version: 3.4.3
Installed Applications:
('core',
 'users',
 'bbbff',
 'agenda',
 'sugarcub',
 'stdimage',
 'bootstrap3',
 'django_admin_bootstrapped',
 'django.contrib.admindocs',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'multiform',
 'registration',
 'endless_pagination',
 'absolute')

Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.contrib.admindocs.middleware.XViewMiddleware')

Traceback:

File "/usr/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.4/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  22.                 return view_func(request, *args, **kwargs)
File "/home/baptiste/sugarcub/users/views.py" in profile
  65.         if urls.is_valid():
File "/usr/lib/python3.4/site-packages/django/forms/formsets.py" in is_valid
  304.         self.errors
File "/usr/lib/python3.4/site-packages/django/forms/formsets.py" in errors
  278.             self.full_clean()
File "/usr/lib/python3.4/site-packages/django/forms/formsets.py" in full_clean
  326.             form = self.forms[i]
File "/usr/lib/python3.4/site-packages/django/utils/functional.py" in __get__
  60.         res = instance.__dict__[self.name] = self.func(instance)
File "/usr/lib/python3.4/site-packages/django/forms/formsets.py" in forms
  142.         forms = [self._construct_form(i) for i in range(self.total_form_count())]
File "/usr/lib/python3.4/site-packages/django/forms/formsets.py" in <listcomp>
  142.         forms = [self._construct_form(i) for i in range(self.total_form_count())]
File "/usr/lib/python3.4/site-packages/django/forms/models.py" in _construct_form
  872.         form = super(BaseInlineFormSet, self)._construct_form(i, **kwargs)
File "/usr/lib/python3.4/site-packages/django/forms/models.py" in _construct_form
  587.             pk = self.data[pk_key]
File "/usr/lib/python3.4/site-packages/django/utils/datastructures.py" in __getitem__
  322.             raise MultiValueDictKeyError(repr(key))

Exception Type: MultiValueDictKeyError at /fr/profil
Exception Value: "'url-0-id'"

我想我把这个问题的所有内容都放在这里了,如果您需要更多,我可以添加。预先感谢您对我的帮助!

您需要为表单集中的每个表单包含 id 字段(这是一个隐藏字段,因此不会向用户显示)。

通常,您会在模板中这样做:

{% for form in formset %}
    {{ form.id }}
    ...

你的情况:

{% for urlform in urls %}
    {{ urlform.id }}

您可能需要为您的其他表单集做类似的事情。