Django: Проблема с удалением объектов базы данных "многие-ко-многим", когда они связаны со сквозной таблицей

Django выдает ошибку, что я не могу удалить объект composer, который раньше был связан с объектом spotifyartist через пользовательскую сквозную таблицу. Мое приложение Django называется 'music', и я использую mysql/mariadb в качестве базы данных

При удалении объекта composer Django выдает следующую ошибку: IntegrityError at /admin/music/composer/(1451, 'Cannot delete or update a parent row: a foreign key constraint fails (bladmuziek.music_composer_spot_artist, CONSTRAINT music_composer_spot__composer_id_4d30a8de_fk_music_com FOREIGN KEY (composer_id) REFERENCES music_composer (id))')

Даже после удаления записи в сквозной таблице для пары композитор + исполнитель Spotify, когда между двумя объектами модели больше нет очевидной связи (для меня), я все равно не могу удалить (ранее связанный) объект композитора или исполнителя Spotify.

Я не могу понять, как я нарушаю ограничение, о котором говорит сообщение об ошибке. Думаю, я не до конца понимаю сообщение об ошибке и не знаю точно, связано ли оно с ограничением, которое я добавил в сквозную модель, или это какое-то другое ограничение. Любые предложения о том, как полностью понять сообщение об ошибке и удалить объект Django, будут приняты с благодарностью. Соответствующие фрагменты моего кода - это модель composer, модель spotifyartist и сквозная таблица ComposerSpotLink, которая предназначена для отслеживания типа отношений между композитором и spot-artist. Эта таблица имеет пользовательское ограничение:

class Composer(models.Model):
first_name = models.CharField(max_length = 50, blank = True)
last_name = models.CharField(max_length = 50)
birth_year = models.SmallIntegerField(default = 0)
death_year = models.SmallIntegerField(default = 0)
spot_artist = models.ManyToManyField('SpotifyArtist', through = 'ComposerSpotLink', related_name = 'composer', blank = True)

class SpotifyArtist(models.Model):
spot_id = models.CharField(validators = [validate_spot_id], max_length = 22, unique = True) #spot_id: is the unique base-62 identifier from Spotify
spot_name = models.CharField(max_length = 255)

class Type(models.IntegerChoices):
PRIMARY = 1, _("Primary")
SECONDARY = 2, _("Secondary")
IGNORE = 3, _("Ignore")
UNVERIFIED = 4, _("Unverified")

class ComposerSpotLink(models.Model):
"""Through model for the relationship between database composer and spotify Artist."""

composer = models.ForeignKey('Composer', on_delete = models.CASCADE, related_name = 'composerspotlink')
spot_artist= models.ForeignKey('SpotifyArtist', on_delete = models.CASCADE, related_name = 'composerspotlink')
type = models.IntegerField(choices = Type.choices, default = Type.UNVERIFIED)

def clean(self):
    if self.type == Type.PRIMARY and ComposerSpotLink.objects.filter(composer = self.composer, \
           type = Type.PRIMARY).exclude(spot_artist = self.spot_artist).exists():
        sa = SpotifyArtist.objects.get(composerspotlink__composer = self.composer, composerspotlink__type = Type.PRIMARY)
        raise ValidationError(_(f'{self.composer} already has a primary spotify artist assigned: {sa}'),
                      code = 'Integrity error: only one primary spotify artist per composer',
                      params = {'composer': self.composer},)

class Meta:
     order_with_respect_to = 'composer'
     constraints = [ UniqueConstraint(fields = ['composer','spot_artist'], name = "spotify_relationship")]

def save(self, *args, **kwargs):
    self.clean()
    super(ComposerSpotLink, self).save(*args, **kwargs)
Вернуться на верх