django - ManyToManyField对象上的Django可变数量的过滤器?
问题描述
我想使用 ManyToManyFeild 指向的对象的两个属性来过滤 ManyToManyField 上的对象。看下面的模型,这是一个经典的用户-项目关系
from django.db import models
class Person(models.Model):
# user = models.OneToOneField(User)
name = models.CharField(max_length=50, blank=False, null=False, default=None, unique=True)
ratings = models.ManyToManyField('Rating',
related_name="persons"
)
class Movie(models.Model):
title = models.CharField(max_length=50, blank=False, null=False, default=None, unique=True)
def __str__(self):
return f"{self.title}"
class Rating(models.Model):
movie = models.ForeignKey(Movie, models.CASCADE)
value = models.SmallIntegerField(blank=False, null=False, default=None)
def __str__(self):
return f"{self.movie}:{self.value}"
所以,我想找到所有对 Movie1 给予高于特定评级和对 Movie2 给予高于特定评级的用户。
我可以用级联过滤器做到这一点:
>>> Person.objects\
.filter(ratings__movie__title='Movie1', ratings__value__gte=5)\
.filter(ratings__movie__title='Movie2', ratings__value__gte=1)\
.all()
[[A<QuerySet [<Person: Person object (1)>]>
但我正在寻找一种方法来过滤任意数量的评级,而不仅仅是 2。
我尝试过使用 Q (在filter()
所有情况下都是单一的),但以下方法不起作用:
>>> Person.objects.filter(
Q(ratings__movie__title='Movie1') & Q(ratings__value__gte=5),\
Q(ratings__movie__title='Movie2') & Q(ratings__value__gte=1)
).all()
<QuerySet []>
更新:
我发现,由于过滤器是惰性的,我可以在一个循环中级联所需数量的过滤器,然后.all()
在最后调用,如下所示:
my_filters = [("Movie1", 2), ("Movie2", 3)]
f = Person.objects
for m,r in my_filters:
f = f.filter(ratings__movie__title=m, ratings__value__gte=r)
selected_persons = f.all()
当然,问题仍然存在,该查询的效率如何......所以问题仍然是如何以最佳效率执行此操作。
感谢帮助!
解决方案
您想要或 Q 对象您当前的尝试和它们,这基本上意味着电影标题必须是 Movie1 AND Movie2 并且评级必须是 5 AND 1。
这可能会如您所愿:-
Person.objects.filter(
(Q(ratings__movie__title='Movie1') & Q(ratings__value__gte=5)) | (Q(ratings__movie__title='Movie2') & Q(ratings__value__gte=1))
).all()
推荐阅读
- javascript - Highcharts 6.0 同步错误
- java - 应用程序崩溃并出现日志错误 Resources$NotFoundException: Resource ID #0x0 on using AlertDialog inside ListviewAdapter
- android - 将 Youtube 链接复制到我的应用程序会在 onActivityResult() 中创建 NPE
- python - 成员变量在多个对象之间共享-python
- reactjs - React - 使用 onClick 方法将状态设置为目标
- java - 从 Java RandomAccessFile 读取时如何设置超时
- php - PHP 和 HTML 下载
- python - 如何将 ndarray 附加到列表并从列表中访问每个存储的 ndarray?
- oracle - Oracle 时区转换
- javascript - 意外的令牌您可能需要适当的加载程序来处理此文件类型。导入strapi sdk