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 }}
您可能需要为您的其他表单集做类似的事情。
我刚刚在处理我的 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 }}
您可能需要为您的其他表单集做类似的事情。