django - 用于交叉多对多关系字段的 Django 查询集
问题描述
我有一个难题,我试图选择具有多对多关系的相互关联的模型,具体取决于每个多对多字段上存在的模型的交集。我试图用 F() 来实现这一点,但没有成功,我认为我对 DB/ORM 的熟练程度不足以解决这个问题。
这是一个例子:
class Event(models.Model):
want_private = models.ManyToManyField('User')
class User(AbstractUser):
events = models.ManyToManyField(Event, related_name='users')
首先,我想从一组用户中选择事件,例如以“a”开头的那些:
users_a = User.objects.filter(username_startswith="a")
所以查询集应该是:
Event.objects.filter(users=users_a)
当事情变得复杂时,我想:
- 排除用户同时在
users
事件want_private
字段、事件字段和查询集中的事件users_a
。 - 包括用户同时在
users
事件字段中的事件,而不是在事件want_private
字段中和在查询集中的事件users_a
。
有没有人有办法解决这个问题?
非常感谢,
卡米尔。
解决方案
根据您上面的评论,似乎用户可以与事件相关联,并且他们的关联是公开的或私有的(我正在解释want_private
这里可能意味着什么)。如果是这种情况,那么我建议您更改数据结构,并将此信息存储在through 模型中。像这样的东西:
class Event(models.Model):
# Remove want_private from here.
class User(AbstractUser):
events = models.ManyToManyField(Event, related_name='users', through=UserEvent)
class UserEvent(models.Model):
""" Through model between event and user. Store want_private here."""
user = models.ForeignKey(User, on_delete=models.CASCADE)
event = models.ForeignKey(Event, on_delete=models.CASCADE)
want_private = models.BooleanField() # This is now a boolean field
我在上面链接到的文档中解释了它是如何工作的。
现在,您的事件查询变得更加简单:
Event.objects.filter(users__username__startswith='a', userevent__wants_private=False)
这将为您提供至少一个用户与该事件相关联的所有事件,并且他们的关联不是私有的。如果某个事件的用户同时属于这两个类别,则此查询将包括该事件。
我在这里对 的含义做了一些假设want_private
。如果want_private
本质上是用户与事件关联的附加标志,那么这个贯穿模型就是正确的数据结构。
推荐阅读
- python - pypdf - 在 pdf 文件中写入时,孟加拉语单词被破坏
- react-native - 如何在 React Native(Android)中正确地将元素聚焦在“位置:”绝对“”视图中
- c - 为什么我的从数组计算平均值的代码不起作用?
- flutter - 从 sql 检索的布尔值作为字符串
- pandas - 创建具有不等长度列表的熊猫数据框
- sql - 如何从通过“路径”列存储的树层次结构中过滤出具有某些继承标志的子树?
- python - 如何修复 TypeError:“NoneType”对象不可迭代
- database-design - 用于在通知源上存储通用过滤器的数据库设计
- javascript - MUI 自动完成自定义选项,不显示所选选项
- javascript - 本地静音视频时,Agora 远程视图发生变化