在Django 1.9中,我有 models.py 中定义的相关对象,如下所示:
from django.db import models
class Course(models.Model):
title = models.CharField(max_length=10)
class Note(models.Model):
course = models.ForeignKey(Course)
当我删除Course
时,我希望通过默认的级联行为删除所有相关的Note
。我得到的是以下行为:
>>> from test1.models import Course, Note
#First, create a Course and associated Note
>>> c1 = Course()
>>> c1.save()
>>> n1 = Note(course=c1)
>>> n1.save()
>>> c1.pk
4
>>> n1.pk
4
#Next, delete the Course, and see if Note deletes too
>>> c1.delete()
(2, {'test1.Course': 1, 'test1.Note': 1})
>>> c1.pk
>>> n1.pk
1 #pk remains
>>> Note.objects.get(pk=4)
Traceback (most recent call last):
... test1.models.DoesNotExist: Note matching query does not exist.
#Finally, try deleting the Note manually
>>> n1.delete()
(0, {'test1.Note': 0})
>>> n1.pk
>>> #finally the pk is gone!
似乎数据库已正确更新,但只有Course对象在本地更新,而Note对象则没有(即保持其pk)。
为什么会这样,我怎样才能获得Note以删除pk以便它与db同步?
额外信息:我需要此行为的原因是我在其他地方使用了if note.pk:
这样的语句来检查给定的Note
是否已保存在数据库中。不幸的是,这种级联删除方式使这些语句无效,因为即使删除了数据库条目,也存在pk。
答案 0 :(得分:2)
这是预期的行为。一旦Django从数据库中获取了某些内容(在这种情况下为n1
),在您再次获取它之前,它不会知道对它的更改(使用Note.objects.get(pk=4)
或n1.refresh_from_db()
。< / p>
当您调用c1.delete()
时,Django会从数据库中删除该行并清除对象上的pk
。它还会删除设置为级联的数据库中的所有相关对象。但是,它无法知道其他已经实例化的对象正在引用该对象 - 它怎么可能?
这是一个相同行为的简单示例,没有外键:
# Fetch a Course
>>> c1 = Course.objects.get(pk=1)
# Fetch the same course again, but save it to a different variable
>>> c2 = Course.objects.get(pk=1)
请注意,您现在在数据库中有两个同一行的实例。现在:
# Delete c1
>>> c1.delete()
# c2 Hasn't changed... how could it? That would be magical.
>>> c2.pk
1
# but if you refresh c2 from the database... it isn't there
>>> c2.refresh_from_db()
DoesNotExist: Course matching query does not exist.