我有以下模型类:
class ContactPerson(models.Model):
name = models.CharField(max_length=30)
def __unicode__(self):
return self.name
class Appartment(models.Model):
contact_person = models.ForeignKey(ContactPerson)
问题:在模板文件中,我希望用户填写联系人姓名,因此我会覆盖contact_person字段,如下所示:
class AppartmentSellForm(ModelForm):
contact_person = forms.CharField(max_length=30)
class Meta:
model = Appartment
在我的视图功能中,我正在执行以下操作以保存提交的表单中的数据:
def appartment_submit(request):
if request.method == "POST":
form = AppartmentSellForm(request.POST)
if form.is_valid():
appartment = form.save(commit=False) # ERROR HERE
cp = models.ContactPerson(name=form.cleaned_data['contact_person'])
appartment.contact_person = cp
appartment.save()
form.save();
return HttpResponseRedirect('/sell/')
else:
form = AppartmentSellForm()
return render_to_response('sell_appartment_form.html', {'form' : form})
错误消息:
#ValueError at /sell/sell_appartment/appartment_submit/
Cannot assign "u'blabla'": "Appartment.contact_person" must be a "ContactPerson" instance.**
我正在使用SQLite和django版本1.1.1
问题:如何解决这个问题?
答案 0 :(得分:1)
我认为您在视图中添加的代码更适合ModelForm的验证。
覆盖模型表单的clean_contact_person
方法并在那里添加代码,以便a)检查名称是否有效,如果是,b)将表单字段的值设置为实际的ContactPerson实例。
类似的东西:(在我的头顶)
class AppartmentSellForm(ModelForm):
contact_person = forms.CharField(max_length=30)
class Meta:
model = Appartment
def clean_contact_person(self):
name = self.cleaned_data['contact_person']
# check the name if you need to
try:
# maybe check if it already exists?
person = models.ContactPerson.objects.get(name=name)
except ContactPerson.DoesNotExist:
person = models.ContactPerson(name=name)
# you probably only want to save this when the form is saved (in the view)
return person
您的视图可能仍需要使用commit=False
(因为您需要保存ContactPerson记录)。您可以使用save_m2m
方法执行此操作。
有关the ModelForm documentation中save_m2m
的更多信息以及the validation documentation中有关清洁字段的信息。
我希望有所帮助,祝你好运!
答案 1 :(得分:0)
您可以执行以下操作之一:
exclude
contact_person
字段,如上所述in point 3 over here ModelForm
中的字段,Django会将其呈现为ModelChoiceField
,除非您实际上希望人们输入名称而不是让下拉列表可供选择