3

2 つの単純なモデルがあります。

class Image(Model):
    photo = models.CharField()

class Box(Model):
    name = models.CharField()
    image = models.ForeignKey(Image, blank=True, null=True)

Image のオブジェクトを削除したい場合、Django は Box モデルに対して select クエリを作成します。

>> Image.objects.all()[0].delete()

>> print len(connection.queries)

2

>> connection.queries

{u'time': u'0.000', u'sql': u'QUERY = u\'SELECT "box"."id", ... FROM "box" WHERE "image"."image_id" IN (%s)\' - PARAMS = (1,)'}
{u'time': u'0.000', u'sql': u'QUERY = u\'DELETE FROM "image" WHERE "id" IN (%s)\' - PARAMS = (1,)'}

ジャンゴ 1.6b2

私は で試しましたがon_delete=models.SET_NULL、sqlite と PostgreSQL でも常に同じ結果が得られました。

4

1 に答える 1

7

Django がオブジェクトを削除すると、関連するオブジェクトのカスケード削除をエミュレートして、それらのdeleteメソッドと関連するシグナルが確実に呼び出されるようにします。https://docs.djangoproject.com/en/stable/topics/db/queries/#deleting-objectsを参照してください

Django がオブジェクトを削除するとき、デフォルトでは、SQL 制約 ON DELETE CASCADE の動作をエミュレートします。つまり、削除するオブジェクトを指す外部キーを持つオブジェクトはすべて削除されます。

Django 1.5+ では、外部キーを に設定することで削除を高速化できますon_delete=DO_NOTHINGhttps://docs.djangoproject.com/en/stable/ref/models/querysets/#django.db.models.query.QuerySet.deleteを参照してください

Django は、オブジェクトをメモリにフェッチしてシグナルを送信し、カスケードを処理する必要があります。ただし、カスケードもシグナルも存在しない場合、Django は高速パスを使用して、メモリにフェッチせずにオブジェクトを削除することがあります。大規模な削除の場合、これによりメモリ使用量が大幅に削減される可能性があります。実行されるクエリの量も削減できます。

于 2013-08-21T13:38:30.560 に答える