首页 > 解决方案 > 基于带参数的子查询创建注释

问题描述

我的应用程序中有两个模型,Event并且Registration,最重要的字段如下:

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 和容量作为参数传递。

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

标签: pythondjangopostgresqldjango-modelsdjango-admin

解决方案


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

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

推荐阅读