【问题标题】:Django Sort By ForeignKey Boolean FieldDjango 按 ForeignKey 布尔字段排序
【发布时间】:2012-09-30 19:44:20
【问题描述】:

我有一个想使用 Django 的 ORM 解决的问题。我有以下课程:

class Company:
    name = models.CharField(max_length=200)

class Event:
    title = models.CharField(max_length=200)
    company = models.ForeignKey(Company)

class Registration:
    attended = models.BooleanField(default=False)
    event = models.ForeignKey(Event)

这些是简单的示例,但基本上一个公司可以有多个事件。当用户注册参加活动时,会为该用户创建一个注册(我知道该字段不存在,这不是问题)。如果用户实际出现在事件中,那么该用户的 Registration 对象将具有“attended=True”。

我目前正在生成报告,我需要的本质上是一种让公司查看他们的所有活动的方法,并按参加者的数量排序(“attended=True”的注册)。

我有一个 SQL 语句,可以让您了解我需要什么(除了“e.title”,显然 QuerySet 会返回整个对象):

SELECT e.title FROM example_event e LEFT JOIN (SELECT event_id,
COUNT(*) attendees FROM example_registration WHERE attended=1 GROUP BY
event_id) r ON (e.id=r.event_id) ORDER BY r.attendees DESC;

这给了我一个正确排序的事件标题结果集。但我真的很想在 ORM 中执行此操作并返回一个 QuerySet。有没有办法做到这一点?我基本上需要类似的东西:

events.annotate(attendees=Count('registration__attended=True'))
                .order_by('attendees')

...我知道那句话是无效的,但它希望能说明我想要完成的事情。此外,我需要始终返回公司的所有事件,因为它是一份报告。他们会想看看他们所有的活动的执行情况,即使他们有 0 名与会者(所以像 events.filter(registration__attended=True) 这样的东西不会给我我需要的东西,因为它只返回公司活动的一个子集)。

在此先感谢,我非常感谢有人在这里提供帮助!

【问题讨论】:

    标签: python sql django django-queryset


    【解决方案1】:

    我不确定您是否要排除使用 extra 方法,但您可以执行以下操作:

    events = Event.objects.extra(
        select={'attendees': 'SELECT COUNT(*) from event_registration' + \
            ' where attended=1 and event_id=event_event.id'}
    ).order_by('attendees')
    

    【讨论】:

    • 我不排除使用额外的,因为它无论如何都会返回一个有效的 QuerySet。太棒了。非常感谢!
    【解决方案2】:

    这应该可行:

    events.filter(registration__attended=True)\
          .annotate(attendees=Count('registration'))\
          .order_by('attendees')
    

    注意filter()annotate() 方法不可交换。所以查询有区别:

    >>> events.annotate(attendees=Count('registration')).filter(registration__attended=True)
    
    >>> events.filter(registration__attended=True).annotate(attendees=Count('registration'))
    

    documentation 中了解更多信息。

    【讨论】:

    • 这对我不起作用,因为它返回所有事件的子集。我需要按排序顺序返回所有事件。
    • 非常感谢您的努力,但这仍然只返回事件的一个子集。我需要所有这些,包括有 0 个注册且参加 = True 的活动。您的回答将他们排除在外。
    猜你喜欢
    • 2014-05-13
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 2013-11-16
    • 2023-03-11
    • 2020-11-25
    • 1970-01-01
    相关资源
    最近更新 更多