在多对多字段Django中按对象值排序

在多对多字段Django中按对象值排序,django,django-queryset,Django,Django Queryset,我需要一些涉及多对多关系的django查询集的排序帮助 我正在制作一个基于语言的对话应用程序,我刚刚完成了一个查询的编写,该查询返回一个名为possibleMatches的查询集,其中包含有人可能想与之聊天的用户。但是,现在我想按照用户在用户语言表中使用的特定语言的级别对这些用户进行排序。我相信解决方案在于使用Django的annotate()函数对QuerySet进行排序,但我一直很难找到准确的语法来进行排序。我也尝试过使用过滤关系,但在运行它时,我得到一个错误,说过滤关系不支持嵌套条件 每个

我需要一些涉及多对多关系的django查询集的排序帮助

我正在制作一个基于语言的对话应用程序,我刚刚完成了一个查询的编写,该查询返回一个名为
possibleMatches
的查询集,其中包含有人可能想与之聊天的用户。但是,现在我想按照用户在
用户语言
表中使用的特定语言的
级别
对这些用户进行排序。我相信解决方案在于使用Django的annotate()函数对QuerySet进行排序,但我一直很难找到准确的语法来进行排序。我也尝试过使用过滤关系,但在运行它时,我得到一个错误,说过滤关系不支持嵌套条件

每个用户都有一个
id
和一个由多对多字段表示的
用户语言列表。每个用户语言对应一个
用户
、一个
语言
、一个
级别
。为清楚起见,以下是我的模型:

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
级别,以升序对
可能匹配的用户进行排序。这是我到目前为止的代码和查询:

sortingLanguage= Language.objects.get(id=1)
possibleMatches.annotate(language_1="languages__language__id=sortingLanguage.id").order_by(language_1.level)

但是我不断地遇到语法错误,我不确定filter()、annotate()、When()和Case()的正确组合是什么,以使其正常工作(我想我把语法与过滤多对多关系的语法混淆了)。有人知道这个的正确语法是什么吗?非常感谢。

您可以先筛选多对多关系,这样只保留引用
排序语言的
用户语言
,然后您可以在该语言的
级别
上订购:

CustomUser.objects.filter(
    languages__language=sortingLanguage
).order_by('languages__level')
CustomUser.objects.filter(
语言\语言=排序语言
).order\u by('languages\u level')
如果排序语言的id已知,则不必首先将该对象提取到内存中,您可以直接根据id对其进行筛选:

CustomUser.objects.filter(
    languages__language_id=1
).order_by('languages__level')
from django.db.models import Max

CustomUser.objects.filter(
    languages__language_id=1
).annotate(
    highest_level=Max('languages__level')
).order_by('highest_level')
CustomUser.objects.filter(
语言\u语言\u id=1
).order\u by('languages\u level')
您可以使用聚合按过滤级别中的最大级别排序:

如果排序语言的id已知,则不必首先将该对象提取到内存中,您可以直接根据id对其进行筛选:

CustomUser.objects.filter(
    languages__language_id=1
).order_by('languages__level')
from django.db.models import Max

CustomUser.objects.filter(
    languages__language_id=1
).annotate(
    highest_level=Max('languages__level')
).order_by('highest_level')
从django.db.models导入最大值
CustomUser.objects.filter(
语言\u语言\u id=1
).注释(
最高级别=最大(“语言级别”)

).order\u by('highest\u level')
语言\u语言\u id=sortingLanguage.id
也没有多大意义。假设一个
用户
没有
排序语言
作为语言,您想将其从
可能匹配
中排除吗?他们总是将
排序语言
作为一种语言,我根据过滤方式确定了这一点,以获得
可能匹配
。但是我也可以用一个简单的解决方案,把没有排序语言的人放在列表的底部谢谢你,我不知道你可以用这种方式过滤多对多的关系。但是,现在当我运行
可能匹配.filter(languages\uu language\u id=sortingLanguage.id).order\u by('languages\uu level')
时,我得到了一个重复的用户,即使我在末尾添加了
.distinct()
。你知道会发生什么吗?我将澄清并说,为了避免重复,我必须在排序之前调用
可能匹配项上的
distinct()
。@Gomes:相同的
语言能否多次出现在同一用户身上?否,用户的
用户语言中必须有不同的
语言
list@Gomes:如果在
.order\u by(…)
之后使用
.distinct()
会怎么样?同样的结果,我仍然有一个重复的