Как удалить OneToOneField класса модели в django
в моем django приложении student_management_system, Student связан с User через OneToOneField. если я удаляю Student, он удаляется, но User (встроенный в django User) не удаляется, он все еще существует в базе данных, т.е. в auth_user из db.sqlite3. как это исправить. код на github: https://github.com/anup30/student_management_system проблема также написана в problem.txt там.
Ваш код выглядит корректно; on_delete=models.КАСКАД должен решить эту проблему. Попробуйте переопределить метод delete() для модели Student:
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone_number = models.CharField(max_length=15)
courses = models.ManyToManyField(Course)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.user.first_name} {self.user.last_name}"
def get_absolute_url(self):
return reverse('student-detail', kwargs={'pk': self.pk})
def delete(self, *args, **kwargs):
self.user.delete() # Delete related User
super().delete(*args, **kwargs)
Не забудьте запустить миграцию, чтобы применить изменения.
Поле OneToOneField
model [Django-doc] не имеет двунаправленных "триггеров". Таким образом, если вы удалите User
, то вместе с ним будет удален и Student
, но если вы удалите Student
, вы не удалите User
вместе с ним.
Таким образом, на самом деле это скорее "необязательное взаимно однозначное поле": необязательное Student
связанное к User
таким образом, у каждого Student
есть User
, но не у каждого пользователя сам по себе есть Student
.
Вы можете реализовать переопределение метода .delete(…)
[Django-doc] из модели Student
, как и предлагалось, но это будет , а не выполняться при "массовом" удалении, поэтому:
Student.objects.filter(pk__in=[1,4,2,5]).delete()
приведет к , а не к удалению соответствующих User
символов, то же самое с сигналами.
Если каждый пользователь является Student
, то имеет смысл настроить пользовательскую модель [Django-doc], в противном случае вы можете переопределить .delete()
, но с помощью запланированного параметра, который регулярно удаляет пользователей без привязки к ученику.
итак, я нашел 2 решения для этой проблемы, одно из которых предложил Антонио Круз, переопределив метод delete в модели Student в models.py
def delete(self, *args, **kwargs):
self.user.delete() # Delete related User
super().delete(*args, **kwargs)
другим решением является использование сигналов в models.py
from django.db.models.signals import post_delete
from django.dispatch import receiver
@receiver(post_delete, sender=Student)
def delete_user_when_student_deleted(sender, instance, **kwargs):
instance.user.delete()