Django:保存对象后未找到外键设置

2 投票
1 回答
1855 浏览
提问于 2025-04-16 11:21

我有一个问题模型和一个多选题选项模型,这两个模型之间有外键关系,指向问题。

class Question(models.Model):
    statement = models.TextField(max_length=1024)
    def save(self, *args, **kwargs):
        super(Question,self).save(*args,**kwargs)
        #ques = Question.objects.get(id = self.id)
        f = open('/tmp/prj/log.txt', 'w')
        choiceobjs = self.choice_set.all()
        if choiceobjs:
           f.write("choices found")
        else:
           f.write("choices not found.. zilch")
        f.close()

 class Choice(models.Model):
    value = models.TextField(max_length=1024)
    question = models.ForeignKey(Question)

现在我重写了问题的保存方法。即使问题已经保存,我在保存方法里还是找不到选项集合!我在日志文件里总是看到“找不到选项……一无所获”。

更新:我是在管理界面创建我的问题,而“选项”对象是“内联”创建的。

所以我想问的问题是——这些“内联”字段/模型和主模型是按什么顺序创建的?我该如何延迟在保存方法中检查外键集合,以便“外键集合”能被看到?

1 个回答

3
class Foo(models.Model):
    pass


class Bar(models.Model):
    foo = models.ForeignKey(Foo)

在使用Foo管理界面中的Bar内联时,Django需要先保存Foo对象,因为Bar对象需要主键来引用它,这个引用是通过ForeignKey实现的:

self.save_model(request, new_object, form, change=False)
form.save_m2m()
for formset in formsets:
    self.save_formset(request, form, formset, change=False)

http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py#L870

这意味着当调用Foosave方法时,内联的Bar对象还没有被保存,因此无法进行查询。所以如果你需要在管理界面保存Foo实例时访问这些对象,就需要想办法解决这个问题(使用Bar内联)。

一种可能的解决方案是连接到Barpost_save信号,查看它引用的是哪个Foo对象,然后执行相关代码。但这样做会在每次更改时触发,即使没有创建Foo对象也会被触发。

撰写回答