Django如何过滤多对多字段中的对象,而不是原始查询集

Posted

技术标签:

【中文标题】Django如何过滤多对多字段中的对象,而不是原始查询集【英文标题】:Django how to filter objects in many to many field, not the original queryset 【发布时间】:2018-01-03 16:10:48 【问题描述】:

我正在尝试过滤查询集的多对多字段中的对象并且遇到困难,大多数其他帖子似乎都解决了根据多对多字段的内容过滤查询集的问题,而我需要过滤多对多字段本身。

型号:

class IngredientsUserNeeds(models.Model):
   user = models.ForeignKey(User, blank=True, null=True)
   drinks = models.ManyToManyField(Drink)

class Drink(models.Model):
    name = models.CharField(max_length = 1000, null=True, blank=True)
    user = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True)

在我的 ListAPI 视图中,我开始过滤

qs = IngredientsUserNeeds.objects.all().filter(user=user)

但是在调用这个之后,我想过滤掉不属于特定用户的 qs 的每个对象中的饮料,例如,

qs = qs.filter(drinks=drink_object)

但是,此调用过滤原始的 IngredientsUserNeeds 查询集,而不是它的 ManyToMany 字段中的项目。如何修改我的过滤器,使其不过滤查询集,而是过滤每个对象的 ManyToMany 字段中的项目?

编辑 1

    for obj in qs:
        obj.drinks = obj.drinks.all().filter(user=user)

我到了这一点,但不幸的是它修改了数据库中的原始查询集。有什么建议可以让我保留原始查询集吗?如果有帮助,这是在 Django Rest Framework ListAPIView 中执行的

【问题讨论】:

对不起,这有点混乱。归根结底,您想保留属于当前用户的饮品的 IngredientsUserNeeds 实例吗?如果是这样,请参阅下面的答案 我的意思是我有一个查询组的成分userneeds 对象,而不是过滤该查询集,我想根据饮料的用户字段是否过滤每个对象的多对多字段包含特定用户 @AlexNelson 你有没有找到解决方案?我需要做同样的事情。 【参考方案1】:

类似的东西?

qs = IngredientsUserNeeds.objects.filter(user=user,drinks__user=user)

【讨论】:

这就是我最初尝试的方法,我得到的结果是我需要的正确对象,但它不会过滤饮料本身。例如,假设查询集有 2 个对象,每个对象如下所示:user: 1,drinks:['coke','sprite'] user:2,drinks:['pepsi','mountaindew'] 和例如,对于百事可乐,用户字段包括 user2,但对于 mountaindew,用户字段不包括 user2。我希望我的过滤器在没有山露的情况下返回 user: 2, Drinks['pepsi']。理解这个例子吗? 感谢您的澄清。我不认为您可以通过单个 django 查询集来实现您想要的。执行上面的查询,然后执行查询: Drink.objects.filter(user=user) 并结合两个结果。我没有其他办法,但如果其他人有更好的主意,我很乐意学习一个有用的技巧:) 所以我会为原始查询集中的每个对象过滤 object.drinks.all() 吗?如何将这些过滤后的饮料查询集返回到原始查询集中? 所以我尝试了 elif userQuery 和 user.is_authenticated(): for obj in qs: obj.drinks = obj.drinks.all().filter(user=user) 但它修改了实际的查询集数据库,你知道的任何解决方法?

以上是关于Django如何过滤多对多字段中的对象,而不是原始查询集的主要内容,如果未能解决你的问题,请参考以下文章

如何过滤和访问 Django QuerySet 中的多对多字段?

在 Django Admin 中过滤多对多框

django - 如何查询仅描述的对象存在于多对多字段中的位置

Django 查询集过滤具有相同多对多字段的对象

如何以 django 形式过滤多对多字段

Django ORM:构造查询,该查询将在多对多字段的最后位置的对象中的字段上查找匹配项