【问题标题】:Filtering across two ManyToMany fields过滤两个多对多字段
【发布时间】:2014-06-03 21:10:46
【问题描述】:

我有一个User 模型和一个Event 模型。我对两者都有以下内容:

class Event(models.Model):
    ...
    timestamp = models.DateTimeField()
    organization_map = models.ManyToManyField(Organization)

class User(AuthUser):
    ...
    subscribed_orgs = models.ManyToManyField('Organization')

我想查找在特定时间范围内创建的所有事件并查找订阅这些组织的用户。我知道如何为此编写 SQL(这很容易),但是使用 Django ORM 执行此操作的 pythonic 方式是什么?

我正在尝试如下:

orgs = Organization.objects.all()
events = Event.objects.filter(timestamp__gt=min_time) # Min time is the time I want to start from
events = events.filter(organization_map__in=orgs)

但是从那里,我如何映射到订阅了 organization 的用户?

我正在尝试像这样映射它:

users = User.objects.filter(subscribed_orgs__in=...

【问题讨论】:

    标签: mysql django orm


    【解决方案1】:

    Django 可以一次连接多个表,因此您应该能够一步完成users 查询:

    events = Event.objects.filter(timestamp__gt=min_time)
    users = User.objects.filter(subscribed_orgs__event__in=events).distinct()
    

    distinct() 是必要的,因为用户可以通过多种方式进行匹配。)

    由于您知道要查找的 SQL,您可以随时检查 Django 生成的 SQL 是否符合您的直觉。查看Django Debug Toolbar 或直接使用connection.queries

    【讨论】:

    • subscribed_orgs__event__in=events -- 这不是假设映射到Organizationsubscribed_orgs 具有属性事件吗?如果我理解正确的话......
    • 因为Event 映射到OrganizationUser 也映射到Organization。它们可以映射到多个Organizations。
    • @KVISH: event 这是从OrganizationEvent 的反向关系。阅读this:“要引用‘反向’关系,只需使用模型的小写名称即可。”
    • 所以基本上你是说如果我有Event 和ManyToManyField 用于Organization,它会自动从Organization 映射?很有趣。
    • @KVISH:是的,没错。在这种情况下,查询将返回订阅了与events 子查询中的任何事件关联的任何组织的所有用户。 Django 将在幕后处理所有的连接。
    猜你喜欢
    • 2011-05-30
    • 2018-06-07
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 2020-03-20
    • 2018-08-22
    • 2014-05-25
    • 2020-05-02
    相关资源
    最近更新 更多