Django - Count a subset of related models. You must specify the number of active coupons for each item.

I have a coupon model that has some fields for determining whether it is active, and a user manager that returns only live coupons. The coupon has an FK for the item.

In an element request, I am trying to annotate the number of active coupons available. However, the set of graphs, apparently, considers all coupons, and not just active.

# 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))

Bits .distinct(), and distinct=Truethere are other reasons - request is that he will return duplicates. It all works just fine, just mentioning it here for completeness.

The problem is that it Countincludes inactive coupons that are filtered out by the user manager.

, 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

, sqlite. SQL - , . , , Django ORM .

+5
2

, - , :

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), .

+3

, ? Model.live, Model.objects.

?

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

All Articles