Django внешний ключ модели on_delete = null, но внешний ключ все равно удаляется - PullRequest
0 голосов
/ 18 июня 2020

Я пытаюсь изменить ссылку на внешний ключ при удалении значения с каскада на null следующим образом:

created_by = models.ForeignKey(CustomUser,on_delete=models.SET_NULL, null=True)

Когда я проверяю это, удаляя запись из CustomUser, я получаю количество объектов в Таблица игр до и после удаления.

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)

1 Ответ

0 голосов
/ 18 июня 2020

Я использовал 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

Это подтверждает, что строка внешнего ключа не была удалена.

I ' m отметив это как принятый ответ, но если кто-то сможет объяснить, как решить вопрос без сброса базы данных, я вместо этого отмечу это как принятый ответ.

...