Почему правило Django on_delete не работает? - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть две модели, подключенные через ForeignKey, вроде этого:

class Album(models.Model):
    name = models.CharField(max_length=128)
    # ...

class Track(models.Model):
    name = models.CharField(max_length=128)
    album = models.ForeignKey(Album, related_name='tracks', null=True, on_delete=models.SET_NULL)
    # ...

Я пишу миграцию данных, в которой я пытаюсь удалить некоторые альбомы:

# -*- coding: utf-8 -*-
# Generated by Django 1.9.13 on 2018-12-12 14:05
from __future__ import unicode_literals

from django.db import migrations


def forwards_func(apps, schema_editor):
    Album = apps.get_model("myapp", "Album")
    db_alias = schema_editor.connection.alias

    for album in Album.objects.using(db_alias).filter(foo='bar'):
        album.delete()

def reverse_func(apps, schema_editor):
    pass

class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0049_blabla'),
    ]

    operations = [
        migrations.RunPython(forwards_func, reverse_func),
    ]

ОднакоЯ получаю эту ошибку:

  File "/usr/local/lib/python2.7/site-packages/django/db/backends/base/base.py", line 211, in _commit
    return self.connection.commit()
IntegrityError: update or delete on table "Album" violates foreign key constraint "f2274d6f2be82bbff458f3e5487b1864" on table "Track"
DETAIL:  Key (id)=(1) is still referenced from table "Track".

Но есть правило on_delete.Не в этом ли смысл правила удаления, чтобы избежать подобных ошибок?Или я что-то упустил?Первоначально я пытался delete на наборе запросов, и я думал, что правило on_delete не поддерживается, и мне пришлось циклически просматривать набор запросов и вызывать удаление в каждом экземпляре.Но, видимо, даже этого недостаточно.Какой смысл on_delete, если даже это не работает?Что я могу сделать?Спасибо.

ОБНОВЛЕНИЕ : В оболочке все работает.Я получаю только ошибку при миграции.

1 Ответ

0 голосов
/ 13 декабря 2018

Вам нужно разрешить album быть действительно нулевым:

album = models.ForeignKey(Album, on_delete=models.SET_NULL, null=True)
...