代码之家  ›  专栏  ›  技术社区  ›  Chris Lawlor

Django-计算相关模型的子集-需要为每个项目的活动优惠券计数添加注释

  •  5
  • Chris Lawlor  · 技术社区  · 14 年前

    我有一个优惠券模型,它有一些字段来定义它是否处于活动状态,还有一个自定义管理器,它只返回实时优惠券。优惠券有一个FK to项目。

    # models.py
    class LiveCouponManager(models.Manager):
        """
        Returns only coupons which are active, and the current
        date is after the active_date (if specified) but before the valid_until
        date (if specified).
        """
        def get_query_set(self):
            today = datetime.date.today()
            passed_active_date = models.Q(active_date__lte=today) | models.Q(active_date=None)
            not_expired = models.Q(valid_until__gte=today) | models.Q(valid_until=None)
            return super(LiveCouponManager,self).get_query_set().filter(is_active=True).filter(passed_active_date, not_expired)
    
    class Item(models.Model):
        # irrelevant fields
    
    class Coupon(models.Model):
        item = models.ForeignKey(Item)
        is_active = models.BooleanField(default=True)
        active_date = models.DateField(blank=True, null=True)
        valid_until = models.DateField(blank=True, null=True)
        # more fields
    
        live = LiveCouponManager() # defined first, should be default manager
    
    # views.py
    # this is the part that isn't working right
    data = Item.objects.filter(q).distinct().annotate(num_coupons=Count('coupon', distinct=True))
    

    这个 .distinct() distinct=True 位的存在有其他原因-查询将返回重复项。一切都很好,只是为了完整起见。

    Count 包括由自定义管理器过滤掉的非活动优惠券。

    有什么办法可以说明 应该使用 live 经理?


    编辑

    以下SQL查询正是我所需要的:

    SELECT data_item.title, COUNT(data_coupon.id) FROM data_item LEFT OUTER JOIN data_coupon ON (data_item.id=data_coupon.item_id)
    WHERE (
        (is_active='1') AND 
        (active_date <= current_timestamp OR active_date IS NULL) AND
        (valid_until >= current_timestamp OR valid_until IS NULL)
    )
    GROUP BY data_item.title
    

    2 回复  |  直到 13 年前
        1
  •  3
  •   Chris Lawlor    14 年前

    如果其他人也有同样的问题,下面是我的工作方法:

    Items = Item.objects.filter(q).distinct().extra(
    
                select={"num_coupons":
                         """
                         SELECT  COUNT(data_coupon.id) FROM  data_coupon
                         WHERE (
                             (data_coupon.is_active='1') AND 
                             (data_coupon.active_date <= current_timestamp OR data_coupon.active_date IS NULL) AND
                             (data_coupon.valid_until >= current_timestamp OR data_coupon.valid_until IS NULL) AND
                             (data_coupon.data_id = data_item.id)
                         )
                         """
                        },).order_by(order_by)
    

    current_timestamp 是的),但确实有效。

        2
  •  0
  •   knutin    14 年前

    你确定你的客户经理真的接到电话了吗?您将管理器设置为Model.live,但在Model.objects中查询普通管理器。

    你试过下面的吗?

    data = Data.live.filter(q)...