使用Django的select_related()和多列外键

时间:2014-09-08 17:10:07

标签: django join foreign-keys django-orm

我有一个多租户应用程序,它为所有租户使用共享表(只有一个数据库,只有一个模式)。

我的表存储来自不同客户的远程系统的实体,所有这些实体都有一个有效的主键(tenant,remote_id):

class Tenant(models.Model):
    company_name = models.TextField()

class Post(models.Model):
    tenant = models.ForeignKey(Tenant)
    remote_id = models.IntegerField()

    class Meta:
        unique_together = (('tenant', 'remote_id'))
        index_together = (('tenant', 'remote_id'))

(从技术上讲,我有自动增量整数主键,但它对我的问题并不重要,如果有所不同,我可以删除它们。)

在彼此之间,实体通过远程ID相互引用,租户总是相同的(租户之间没有交叉引用):

class Comment(models.Model):
    tenant = models.ForeignKey(Tenant)
    remote_id = models.IntegerField()
    post_remote_id = models.IntegerField()

    class Meta:
        unique_together = (('tenant', 'remote_id'))
        index_together = (('tenant', 'remote_id'))

Django不支持多值外键,因此我无法声明我的外键'就这样。

现在,当从本地数据库中检索实体时,我想通过SQL JOIN检索同一查询中的外键引用实体。通常情况下,你会使用Django的select_related(),但由于我还没有将它们声明为外键,我无法使用它。

这是我想要做的一个例子(并且只用一个查询就可以访问数据库!):

comments = Comment.objects.filter(author='Ernest').select_related()
commented_post_titles = [comment.post.title for comment in comments]

还有另一种方法可以以干净的方式获得相同的东西吗?我可以覆盖管理器类并使用JOIN执行自定义SQL。但是,我如何干净地创建模型实例并使它们相互链接而不会完全破坏Django的模型系统?

我首选的解决方案当然是某种models.ForeignKey子类,其行为与常规外键(支持select_related(),遍历等)相同,但需要额外的tenant列条件考虑到了。可以写出类似的东西吗?

强调:这些是简单的1对n关系。引用的实体可能不存在于我的本地数据库中(这就是为什么我不首先将这些关系转换为人工外键),但是那里有保证完全是0..1相关实体,绝不是多个实体。

0 个答案:

没有答案