Django-检查是否存在非外键整数字段作为另一个模型的主键?

时间:2018-07-11 15:46:52

标签: python django

假设您具有以下旧版模型:

class Foo(models.Model):
    bar_id = models.IntegerField(null=True, blank=True)
    # more fields

bar_id应该引用Bar模型中的主键,但是由于某些原因,它没有注册为外键。现在,如何过滤掉所有没有相应Foo对象的Bar个对象?

2 个答案:

答案 0 :(得分:1)

我们可以列出Bar的主键列表,然后过滤掉引用该主键的所有Foo

Foo.objects.exclude(bar_id__in=Bar.objects.all().values_list('pk', flat=True))

这是一个QuerySet,它将为所有Foo个对象赋予“ 无效bar_id(因此,id指的是不存在的Bar)。

但是最好使用ForeignKey,因为那样大多数数据库将以透明的方式强制。结果,数据库通常确保根本不存在这样的行。通常,您还向其中添加 triggers ,以防万一引用的Bar对象被删除。

答案 1 :(得分:1)

阅读一些评论使我明白,OP宁愿实现外键,但由于数据库中的数据损坏/丢失而不能这样做。

两种解决方案:

  1. 在模型中将列标记为外键,但不要强制执行 在数据库中(使用--fake进行迁移时,请使用manage.py标志 文件。这种方法实际上有助于更好地定义您的业务 /建模逻辑并在本地开发和实施中加强数据完整性 环境。
  2. 在模型中将该列标记为外键并使用 db_constraint=False标志。阅读更多here。使用这种方法 适用于已经损害数据完整性的旧系统 而且您只需要使用Django的ORM自然连接即可。