【问题标题】:Creating/saving database objects in django ModelForm save method在 django ModelForm 保存方法中创建/保存数据库对象
【发布时间】:2014-12-09 06:00:21
【问题描述】:

我有一个模型表单 JobPosting 和一个自定义字段 location_query,我用它来为模型字段 location 生成数据。为此,我需要为location 字段创建一个Address 对象并将其保存到数据库中。我相信保存此对象的正确时间在JobPosting 的重载save 方法内。

虽然创建并保存了新的Address 对象,但它并没有保存为JobPostinglocation 字段的值,我不知道为什么。

下面是一个简化的例子:

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

令人讨厌的是,上面的代码导致 JobPosting 的位置被保存为 None,但如果我将地址保存在 clean_location 函数中,它可以正常工作。显然我不想将数据库对象保存在一个干净的函数中,但我正在努力弄清楚为什么会这样。

【问题讨论】:

  • instance = super(AttorneyJobPostingForm, self).save(commit=commit, *args, **kwargs) 这是什么? AttorneyJobPostingForm ?
  • 哎呀。我在简化时忘记编辑了
  • 好的.. 现在告诉我这是什么self.instance
  • 据我了解,ModelForm 使用实例作为底层模型实例。
  • 你检查了吗?你在 self.instance 中有什么?

标签: django python-2.7 django-forms django-1.6


【解决方案1】:

解决方法是手动设置location_id。自从我看到它在所有其他情况下发生以来,我一直在假设,<field>_id 成员在保存时会自动填写,它会在这里发生。我不知道为什么不是,但在保存位置后添加 instance.location_id = instance.location.uuid 就可以了。

我还将 instance.location 设置代码移到了超级保存之后(如@Sławek 所建议),因为如果在创建表单时没有传入 self.instance,它将不会一直存在。

新代码如下所示:

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

【讨论】:

  • 在这种情况下,您将节省两倍 instance。将其更改为commit=False。显示 Address() 模型。
猜你喜欢
  • 1970-01-01
  • 2018-07-07
  • 2018-10-10
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多