为什么Django ORM在删除对象之前进行选择查询?

Use*_*ser 1 django orm

我有两个简单的模型:

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

class Box(Model):
    name = models.CharField()
    image = models.ForeignKey(Image, blank=True, null=True)
Run Code Online (Sandbox Code Playgroud)

当我想删除Image的对象时,Django在Box模型上进行选择查询:

>> 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,)'}
Run Code Online (Sandbox Code Playgroud)

Django 1.6b2

我试过on_delete=models.SET_NULL,也与sqlite和PostgreSQL总是相同的结果.

Mar*_*vin 6

当Django删除一个对象时,它会尝试模拟相关对象的级联删除,以确保delete调用它们的方法和相关信号.请参阅https://docs.djangoproject.com/en/stable/topics/db/queries/#deleting-objects

当Django删除一个对象时,默认情况下它会模拟SQL约束ON DELETE CASCADE的行为 - 换句话说,任何具有指向要删除的对象的外键的对象都将随之删除.

使用Django 1.5+,您可以通过设置外键来快速删除路径on_delete=DO_NOTHING.请参阅https://docs.djangoproject.com/en/stable/ref/models/querysets/#django.db.models.query.QuerySet.delete

Django需要将对象提取到内存中以发送信号和处理级联.但是,如果没有级联和没有信号,那么Django可能会采用快速路径并删除对象而不会进入内存.对于大型删除,这可能会导致内存使用量大幅减少.执行查询的数量也可以减少.