【问题标题】:Creating annotation based on subquery with parameters基于带参数的子查询创建注释
【发布时间】:2021-11-03 18:43:28
【问题描述】:

我的应用中有两个模型,EventRegistration,其中最重要的字段如下:

class Event(models.Model):
    ...
    capacity = models.IntegerField()
    ...
class Registration(models.Model):
    timestamp = models.DateTimeField(auto_now_add=True)
    event = models.ForeignKey(Event, on_delete=models.CASCADE)
    uses_bus = models.BooleanField(default=False)
    is_vegan = models.BooleanField(default=False)
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        default=None)

更新

这可以通过在Registration 模型上实现一个字段来解决,该字段指示注册是否是#capacity 注册之一。可以实现吗?

原来的问题

现在,无论是在字段中还是在管理员中,我都试图获取用户标记为uses_bus 的注册数量以及用户标记为is_vegan 的注册数量。这可能是这样的:

class EventAdmin(admin.ModelAdmin):
    list_display = ('title', 'date', 'nr_registrations', 'nr_bus')
    inlines = [RegistrationInline]

    def get_queryset(self, request):
        queryset = super(EventAdmin, self).get_queryset(request)
        return queryset.annotate(
            nr_registrations = Count('registration'),
            nr_bus = Count('registration', filter=Q(registration__uses_bus=True)),
            nr_vegan = Count('registration', filter=Q(registration__is_vegan=True)),
        )

    def nr_registrations(self, obj):
        return obj.nr_registrations
    
    def nr_bus(self, obj):
        return obj.nr_bus
    
    def nr_vegan(self, obj):
        return obj.nr_vegan

但这显然会找到巴士注册的总数,而不是由于容量限制而实际可以参加活动的巴士注册数量。

在 SQL 中我会这样解决:

SELECT SUM(uses_bus)
FROM (SELECT CAST(uses_bus AS INTEGER)
     FROM events_registration WHERE event_id = *event id* ORDER BY id LIMIT *capacity*)
AS a

但我不能这样做,因为即使我会使用 RawSQL,我也无法使用 F() 将事件 ID 和容量作为参数传递。

这可以解决吗?我也愿意扩充模型、添加字段等。

【问题讨论】:

  • 限制只是<myQuery>[:capacity]
  • 我对此很熟悉,但是我不确定如何将其实施到我面临的问题中,您能否提供一个示例?
  • @sverrirarnors 你在 django 中寻找 group_by 查询吗?您想要计算事件的总注册量。
  • 或者只是返回obj.capacity if obj.capacity <= obj.nr_registrations else obj.nr_registrations

标签: python django postgresql django-models django-admin


【解决方案1】:

BrianD 已经说过,您可以检查 容量calculated no 以获取由于容量限制而实际可以参加活动的巴士注册数量。

def nr_bus(self, obj):
    if obj.capacity <= obj.nr_bus:
        return obj.capacity
    return obj.nr_bus
    
def nr_vegan(self, obj):
    if obj.capacity <= obj.nr_vegan:
         return obj.capacity
    return obj.nr_vegan

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 2022-01-19
    • 2018-04-16
    • 1970-01-01
    相关资源
    最近更新 更多