Search code examples
djangodjango-modelsdjango-piston

Simple Django filter query: group by primary key?


I am running a filter query in Django with range. I thought filter always returned a queryset that was grouped by the primary key, but it seems not.

These are my models:

class MCode(models.Model):
    code = models.CharField(max_length=16)
class Product(models.Model):
    id = models.CharField(max_length=40, primary_key=True, db_index=True)
    mcode = models.ForeignKey(MCode, null=True, blank=True, db_index=True)
class Review(models.Model):
    review_id = models.CharField(max_length=32, primary_key=True, db_index=True) 
    product = models.ForeignKey(Product, db_index=True) 
    rating = models.IntegerField() 
    time = models.DateTimeField(db_index=True) 

And this is my code:

mcode = 'M83'
base = Product.objects
tcode_obj = MCode.objects.filter(code=mcode.upper())
return base.filter(tcode=tcode_obj, 
                   review__time__range=[date_from, date_to])

I'm getting five results, but three of them have the same primary key. It looks like I'm getting a result for each review, not each product.

Does anyone know how could I group these products by ID, and annotate with the count of the attached reviews?


Solution

  • When you select based on something that could match multiple times, such as Product with Reviews during a range of time, each match is added to the queryset, even if it's a duplicate of an item already there. There's actually times where you might want this behavior, but if you need to limit the queryset to just unique items, use .distinct() at the end of your query. Getting duplicates is also common when using logical ORs in your query, so be aware of times you do that and remember to use .distinct() there as well.