繁体   English   中英

使用django中的自定义外键字段保存表单中的数据

[英]save data from form with custom foreign key field in django

我有以下Model类:

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版

问题:如何解决这个问题?

我认为您在视图中添加的代码更适合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方法执行此操作。

ModelForm文档中有关于save_m2m的更多信息,以及有关验证文档清理字段的信息

我希望有所帮助,祝你好运!

您可以执行以下操作之一:

  1. 尝试exclude contact_person字段,如此处的第3点所述
  2. 或者您可以不覆盖ModelForm的字段,Django会将其呈现为ModelChoiceField ,除非您实际上希望人们输入名称而不是有可供选择的下拉列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM