保存带下拉菜单的表单集时出现完整性错误:XXX_id 不能为空
我正在尝试创建一个表单集合,其中每个表单(PropertySelector)都有一个下拉菜单(PropertySelector.property),而这个菜单中的每个选项都是指向另一个模型(Property)的外键引用。
但是,当我尝试提交并保存这个表单集合时,我遇到了以下问题:
Exception Type: IntegrityError
Exception Value: testproj_propertyselector.property_id may not be NULL
这是什么问题,我该如何解决呢?我的完整代码在下面。谢谢。
编辑:我觉得这可能是inline_formset的问题(也可能和MySQL有关)。请帮我想个解决办法。
这个项目叫做testproj,我的应用程序也叫testproj。
首先,我们需要填充Property:
>>> from testproj.models import Property
>>> p = Property(name='prop1', basic=True)
>>> p.save()
>>> p = Property(name='prop2', basic=True)
>>> p.save()
models.py
from django.db import models
class PropertySet(models.Model):
name = models.CharField(max_length=50)
class Property(models.Model):
name = models.CharField(max_length=50)
basic = models.BooleanField()
def __unicode__(self):
return u'%s' % (self.name)
class PropertySelector(models.Model):
property_set = models.ForeignKey(PropertySet)
title = models.CharField(max_length=50)
property = models.ForeignKey(Property)
forms.py
from django.forms import ModelForm, TextInput, Select, ModelChoiceField
from django.db.models import Q
from testproj.models import Property, PropertySet, PropertySelector
class PropertySetForm(ModelForm):
class Meta:
model = PropertySet
def PropertySelForm():
PropertyQueryset = Property.objects.filter(Q(basic=True))
class PropertySelectorForm(ModelForm):
property = ModelChoiceField(
queryset=PropertyQueryset,
widget=Select(attrs={'class': 'property'})
)
def __init__(self, *args, **kwargs):
super(ModelForm, self).__init__(*args, **kwargs)
self.css_class = "prop_sel"
class Meta:
model = PropertySelector
fields = ("property_set", "title")
widgets = {"title" : TextInput(attrs={"class" : "title"})}
return PropertySelectorForm
views.py
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.forms.models import inlineformset_factory
from testproj.models import PropertySet, PropertySelector
from testproj.forms import PropertySetForm, PropertySelForm, PropertySelForm
def index(request):
property_selector_form = PropertySelForm()
PropertySelectorFormSet = inlineformset_factory(PropertySet, PropertySelector, form=property_selector_form)
if request.method == "POST":
property_set_form = PropertySetForm(request.POST)
if property_set_form.is_valid():
saved_property_set = property_set_form.save()
prop_sel_formset = PropertySelectorFormSet(request.POST, instance=saved_property_set)
if prop_sel_formset.is_valid():
prop_sel_formset.save()
else:
property_set_form = PropertySetForm()
prop_sel_formset = PropertySelectorFormSet()
return render_to_response(
"testproj/index.html",
{
"property_set_form": property_set_form,
"prop_sel_formset": prop_sel_formset
},
context_instance=RequestContext(request)
)
index.html(模板):
{% block content %}
<head>
</head>
<body>
<form method="post" action=""> {% csrf_token %}
{{ property_set_form.as_p }}
{{ prop_sel_formset.management_form }}
{% for form in prop_sel_formset %}
{{ form }}
{% endfor %}
<input type="submit" value="Submit">
</form>
</body>
{% endblock %}
1 个回答
1
因为你没有把 property_id
加入到你的 form.Meta
里,所以它没有被保存。把字段去掉,它就能正常工作了:
def PropertySelForm():
PropertyQueryset = Property.objects.filter(Q(basic=True))
class PropertySelectorForm(ModelForm):
property = ModelChoiceField(
queryset=PropertyQueryset,
widget=Select(attrs={'class': 'property'})
)
def __init__(self, *args, **kwargs):
super(ModelForm, self).__init__(*args, **kwargs)
self.css_class = "prop_sel"
class Meta:
model = PropertySelector
#fields = ("property_set", "title")
widgets = {"title" : TextInput(attrs={"class" : "title"})}
return PropertySelectorForm
我会把 PropertySelForm
改名为 property_selectorform_factory
,不过这只是我个人的想法。:)