【发布时间】:2020-09-05 17:37:32
【问题描述】:
对于涉及多对多关系的 django 查询集,我需要一些排序帮助。
我正在制作一个基于语言的对话应用程序,并且我刚刚完成了一个查询,该查询返回一个名为 possibleMatches 的查询集,其中包含某人可能想要与之聊天的用户。但是,现在我想按他们在user languages 表中的特定语言的level 对这些用户进行排序。我相信解决方案在于使用 Django 的 annotate() 函数对查询集进行排序,但我一直无法找到准确的语法来执行此操作。我也尝试过使用过滤关系,但是在运行它时,我得到一个错误,说过滤关系不支持嵌套条件。
每个用户都有一个id 和一个由多对多字段表示的user languages 列表。每种用户语言对应一种user、一种language和一种level。为清楚起见,这是我的模型:
class CustomUser(AbstractUser):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
class Language(models.Model):
id = models.IntegerField(primary_key=True, choices=SUPPORTED_LANGUAGES)
class UserLanguage(models.Model):
language = models.ForeignKey(Language, on_delete=models.DO_NOTHING)
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='languages', on_delete=models.DO_NOTHING)
level = models.IntegerField(choices=LANGUAGE_PROFICIENCIES, null=False, blank=False)
无论如何,我想根据语言1 的level 对possibleMatches 中的用户进行升序排序。这是我到目前为止的代码和查询:
sortingLanguage= Language.objects.get(id=1)
possibleMatches.annotate(language_1="languages__language__id=sortingLanguage.id").order_by(language_1.level)
但我不断收到语法错误,我不确定 filter()、annotate()、When() 和 Case() 的正确组合是什么才能使其正常工作(我想我是使语法与过滤多对多关系的语法混淆)。有谁知道正确的语法是什么?非常感谢您。
【问题讨论】:
-
languages__language__id=sortingLanguage.id也没有多大意义。想象一下User没有sortingLanguage作为语言,你想把它从possibleMatches中排除吗? -
他们将始终将
sortingLanguage作为一种语言,我根据我的过滤方式确保了这一点,以便获得possibleMatches。但我也可以使用一个简单地将没有排序语言的每个人放在列表底部的解决方案