django - Django 模型外键 on_delete=null 但外键还是被删除了
问题描述
我正在尝试将删除值上的外键引用从级联更改为 null,如下所示:
created_by = models.ForeignKey(CustomUser,on_delete=models.SET_NULL, null=True)
当我通过从 CustomUser 中删除记录来测试这一点时,我会在执行删除之前和之后获得 Games 表中对象的计数。
p = Games.objects.count()
print(p) #outputs 100
print(Games.objects.filter(created_by=2)) #outputs <QuerySet [<Games: 181 79 None>]>
cu = CustomUser.objects.get(pk=2)
cu.delete()
p = Games.objects.count()
print(p) #outputs 98
print(Games.objects.filter(created_by=2)) # outputs <QuerySet []>
我尝试使用其他值进行删除,但唯一不从数据库中删除行的值是保护。相反,它会引发保护错误
raise ProtectedError(
django.db.models.deletion.ProtectedError: ("Cannot delete some instances of model 'CustomUser' because they are referenced through a protected foreign key: 'Games.created_by'", <QuerySet [<Games: 181 79 None>]>)
CustomUser 和 Games 模型的代码
class CustomUser(AbstractBaseUser, PermissionsMixin):
id = models.BigAutoField(primary_key=True)
username = models.CharField(max_length=15, unique=True)
email = models.EmailField(max_length=128, unique=True)
password = models.CharField(max_length=254)
salt = models.CharField(max_length=128)
email_verified = models.BooleanField(default=False)
avatar = models.ImageField(blank=True, null=True)
date_joined = models.DateTimeField(default=timezone.now)
last_updated = models.DateTimeField(blank=True, null=True)
is_active = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
objects = CustomUserManager()
def __str__(self):
return self.email
class Games(models.Model):
CATEGORY = (
('general knowledge','general knowledge'),
('science','science'),
('mythology','mythology'),
('sports','sports'),
('geography','geography'),
('history','history'),
('politics','politics'),
('art','art'),
('celebrities','celebrities'),
('animals','animals'),
('vehicles','vehicles'),
('entertainment','entertainment'),
('random','random')
)
id = models.BigAutoField(primary_key=True)
number_of_questions = models.SmallIntegerField()
number_of_players = models.SmallIntegerField()
start_time = models.DateTimeField(default=timezone.now)
category = models.CharField(max_length=18, choices=CATEGORY)
created_by = models.ForeignKey(CustomUser,on_delete=models.SET_NULL, null=True)
result_id = models.ForeignKey(Results, on_delete=models.CASCADE, null=True, blank=True)
sudden_death_id = models.ForeignKey(SuddenDeath, on_delete=models.CASCADE, null=True, blank=True)
objects = models.Manager()
def __str__(self):
return '%s %s %s' % (self.id, self.result_id, self.sudden_death_id)
解决方案
我曾经django-extensions
reset_db
重置我的数据库,删除了所有迁移并重新运行。makemigrations
&migrate
从我的灯具中导入相同的数据集后,我再次运行了这段代码
p = Games.objects.count()
print(p) #output 100
print(Games.objects.filter(created_by=2)) # output <QuerySet [<Games: 181 79 None>]>
cu = CustomUser.objects.get(pk=2)
cu.delete()
p = Games.objects.count()
print(p) #output 100
print(Games.objects.get(pk=181)) #output 181 79 None
这证实了外键行没有被删除。
我将此标记为已接受的答案,但如果有人能够解释如何在不重置数据库的情况下解决问题,我会将其标记为已接受的答案。
推荐阅读
- graph - 在 Power BI 中向折线图添加多个字段
- javascript - 按日期排序并获取 CouchDB 视图中的最新值
- reverse-engineering - 需要 Ghidra 自动分析常见的 Microsoft C 函数
- r - 是否需要运行 DLNM 包的行数
- flutter - Flutter firebase_messaging最新版本上的FirebaseMessaging.configure()错误
- c - 算术问题:前向声明和除法后总是返回零
- oracle - ORA-03113: 当我尝试启动空闲实例时,通信通道上的文件结束错误
- sql-server - LDAP / Active Directory : 多个 CN 和 SQL
- python - 列名列表中最大年份和季度的 Python 正则表达式
- r - `testthat::expect_known_value` 的第 3 版替代品是什么?