我的模型表单JobPosting
带有自定义字段location_query
,我用它来为模型字段location
生成数据。在这样做时,我需要为Address
字段创建一个location
对象并将其保存到数据库中。我相信保存此对象的正确时间是save
的重载JobPosting
方法。
创建并保存新的Address
对象时,它不会保存为JobPosting
的{{1}}字段的值,而且我是不知道为什么。
以下是一个简化示例:
location
令人讨厌的是,上面的代码导致JobPosting的位置保存为class Address(Model):
pass
class JobPosting(Model):
location = ForeignKey(Address, blank=True, null=True)
class JobPostingForm(forms.ModelForm):
location_query = forms.CharField(max_length=256)
class Meta:
model = JobPosting
fields = (
'location_query',
'location', # hidden field
}
def clean_location(self):
data = self.data.get('location_query')
addr = Address()
# do some stuff here to dump data into addr
return addr
def save(self, commit=True, *args, **kwargs):
if self.instance.location and not self.instance.location.uuid :
self.instance.location.save()
instance = super(JobPostingForm, self).save(commit=commit, *args, **kwargs)
return instance
,但如果我将地址保存在None
函数中,则它可以正常工作。显然,我不想将数据库对象保存在一个干净的函数中,但是我想把它弄出来试图找出原因。
答案 0 :(得分:0)
解决方案是手动设置location_id
。我一直在假设,因为我看到它发生在所有其他情况下,<field>_id
成员自动填写保存,它会发生在这里。我不确定为什么不是,但在保存位置后添加instance.location_id = instance.location.uuid
就可以了。
我还将instance.location设置代码移动到超级保存之后(由@Sławek建议),因为如果在表单创建时没有传入,则实例将不会一直存在。
新代码看起来像这样:
def save(self, commit=True, *args, **kwargs):
instance = super(JobPostingForm, self).save(commit=commit, *args, **kwargs)
if instance.location and not instance.location.uuid :
instance.location.save()
instance.location_id = instance.location.uuid
instance.save()
return instance