【发布时间】:2018-04-01 17:32:15
【问题描述】:
假设我有 2 个模型 Coupon 和 UserRedemption(当然还有一个用户模型)。它们看起来像:
Coupon(models.Model):
offer = models.TextField() # not important to this task
limited_use = models.BooleanField(default=False)
max_uses = models.IntegerField(default=0)
UserRedemption(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
coupon = models.ForeignKey(Coupon)
非常基本。我的应用程序中有优惠券,每张优惠券都有一个由不同用户兑换的次数列表。有些优惠券是“有限使用”的,即特定用户只能使用一定次数。
我的目标:返回一个优惠券列表,不包括发出请求的用户使用的最大次数的优惠券。
我试图通过在优惠券上标注当前用户兑换的次数 (n_user_redemptions) 并过滤列表中limited_use = False OR max_uses > n_user_redemptions 的优惠券来做到这一点。这是我在 Coupon 类上尝试的方法:
@classmethod
def get_available_user_coupons(cls, user):
coupon_redemption_count = Count('userredemption', filter=Q(userredemption__user=user))
return cls.objects.annotate(n_user_redemptions=coupon_redemption_count)
.filter(Q(limited_use=False) | Q(max_uses__gt=F('n_user_redemptions')))
但是,它没有正确过滤从请求中传入的用户。它总是将 n_user_redemptions 设置为所有用户对该优惠券的所有兑换的计数,而不仅仅是给定用户的兑换。我已经测试过,如果limited_use 设置为False,并且该优惠券的总兑换次数(所有用户)少于max_uses,它会正确返回优惠券。而且我已经确认我正确地传递了用户。
我不确定我在这里缺少什么。我已经非常广泛地阅读了 django 聚合文档,看起来这应该可以工作。任何帮助将不胜感激。
只是进一步的更新:
我检查了生成的 SQL 并注意到查询是否相同:
coupon_redemption_count = Count('userredemption', filter=Q(userredemption__user=user))
或
coupon_redemption_count = Count('userredemption')
不确定过滤器参数的行为应该在 Count 中是什么。
相关SQL:
SELECT "coupon_coupon"."id", "coupon_coupon"."offer", "coupon_coupon"."limited_use", "coupon_coupon"."max_uses",
COUNT("userredemption_userredemption"."id") AS "n_user_redemptions"
FROM "coupon_coupon"
LEFT OUTER JOIN "userredemption_userredemption"
ON ("coupon_coupon"."id" = "userredemption_userredemption"."coupon_id")
GROUP BY "coupon_coupon"."id"
ORDER BY "coupon_coupon"."id" DESC
在任何地方都没有提到用户?
【问题讨论】:
标签: python django django-models django-rest-framework