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

时间:2013-08-21 13:17:33

标签: django orm

我有两个简单的模型:

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

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

当我想删除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,)'}

Django 1.6b2

我尝试过使用on_delete=models.SET_NULL,同时使用sqlite和PostgreSQL的结果也一样。

1 个答案:

答案 0 :(得分: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可能会采用快速路径并删除对象而不会进入内存。对于大型删除,这可能会导致内存使用量大幅减少。执行查询的数量也可以减少。