【问题标题】:How to do complex join in Django如何在 Django 中进行复杂的连接
【发布时间】:2017-09-13 08:07:34
【问题描述】:

我有自定义用户模型和两个模型,都使用 ForeinKey 来同时访问两个用户:

class Feature1(models.Model):
    user1 = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='u1')
    user2 = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='u2')

    some field....
    percentage = models.FloatField()

class Feature2(models.Model):
    user1 = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='us1')
    user2 = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='us2')

    some fields...
    property = models.PositiveIntegerField()

然后我使用查询集检索特定用户的所有对

queryset = Feature1.objects.filter(u1=self.request.user).all().order_by('-percentage')

但是我需要的是,在这个查询集中也有来自 Feature2 模型的数据(对于每对特定的用户,如果存在) 并能够通过 Feature2 中的“属性”订购查询集

怎么做?我研究了 django 文档,但没有结果。

【问题讨论】:

  • 您是否考虑过使用select_related()
  • 大概就是这样,但我不知道如何正确使用它。我的情况不像 django 例子那么简单。
  • 您是否想要Feature2 中的所有字段,其中Feature2 中的user1 等于Feature1 中的user1Feature2 中的user2 等于@987654331 @在Feature1?
  • @MattCremeens 是的,完全正确

标签: python django python-3.x django-models django-queryset


【解决方案1】:

一种尝试是首先从第一个关系中获取所有 user1suser2s

u1 = Feature1.objects.all().values_list('user1', flat=True)
u2 = Feature1.objects.all().values_list('user2', flat=True)

然后从与这些用户匹配的第二个关系中获取Feature2 对象

queryset = Feature2.objects.filter(user1__in=u1, user2__in=u2).order_by('-percentage')

我还想为您的数据库设计提供一个替代方案,我认为这将帮助您更有效地查询您的模型。为什么不将Feature2 更改为ForeignKeyFeature1,就像这样

class Feature2(models.Model):
    feature1 = models.ForeignKey(Feature1, verbose_name="Feature 1")

    ...

那么你可以这样加入两者

queryset = Feature2.objects.filter(feature1__in=Feature1.objects.filter(u1=self.request.user)).order_by('-percentage')

【讨论】:

  • 这是一个嵌套循环连接。有什么方法可以更有效地做到这一点?
  • 就是这样,但是一个查询,我们有很多。我想通过一个对 db 的查询来做到这一点(在我的例子中是 postgresql)。
  • 我必须回复你。 @sudo,我确信有一种更有效的方法,但这是我想到的。
  • @Maxim Koro 我已经编辑了我的答案,希望更适合您的目的。
  • @Matt Cremeens 这与最初的概念背道而驰。每对唯一的用户都有 Feature1 记录。 Feature2 也一样。虽然 F2 只有在 F1 存在时才有意义,但记录 F2 可以出现在 F1 之前。无论如何,你的方式是有道理的。我会考虑一下。现在我倾向于在 Django 中使用原始 SQL。
猜你喜欢
  • 2010-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-20
  • 2018-06-16
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多