Opened 7 years ago

Closed 7 years ago

#28724 closed Bug (invalid)

QuerySet filter across m2m returns incorrect number of objects

Reported by: Zach Owned by: nobody
Component: Uncategorized Version: 1.11
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

# models
from django.db import models

class ProductArea(models.Model):
  name = models.CharField(max_length=100)

class Product(models.Model):
  name = models.CharField(max_length=100)
  product_areas = models.ManyToManyField(ProductArea, through='Relationship')

class MembershipLevel(models.Model):
  name = models.CharField(max_length=100)

class Relationship(models.Model):
  product = models.ForeignKey(Product)
  product_area = models.ForeignKey(ProductArea)
  membership_level = models.ForeignKey(MembershipLevel)
from myapp.models import MembershipLevel
from myapp.models import ProductArea
from myapp.models import Relationship
from myapp.models import Product

p1, _ = Product.objects.get_or_create(name='My Product')
p2, _ = Product.objects.get_or_create(name='Another Product')
p3, _ = Product.objects.get_or_create(name='Yet another product')

a1, _ = ProductArea.objects.get_or_create(name='Air')
a2, _ = ProductArea.objects.get_or_create(name='Land')
a3, _ = ProductArea.objects.get_or_create(name='Sea')

m1, _ = MembershipLevel.objects.get_or_create(name='gold')
m2, _ = MembershipLevel.objects.get_or_create(name='bronze')
m3, _ = MembershipLevel.objects.get_or_create(name='silver')

Relationship.objects.get_or_create(product=p1, product_area=a1, membership_level=m1)
Relationship.objects.get_or_create(product=p1, product_area=a2, membership_level=m2)
Relationship.objects.get_or_create(product=p1, product_area=a3, membership_level=m3)
Relationship.objects.get_or_create(product=p2, product_area=a1, membership_level=m1)
Relationship.objects.get_or_create(product=p2, product_area=a2, membership_level=m2)
Relationship.objects.get_or_create(product=p2, product_area=a3, membership_level=m3)
Relationship.objects.get_or_create(product=p3, product_area=a1, membership_level=m1)
Relationship.objects.get_or_create(product=p3, product_area=a2, membership_level=m2)
Relationship.objects.get_or_create(product=p3, product_area=a3, membership_level=m3)

# "total found: 3".
print('total found: %s' % Product.objects.count())

# "total with filter found: 9".
print('total with filter found: %s' % Product.objects.filter(product_areas__relationship__membership_level__name='gold').count())

Change History (1)

comment:1 by Tim Graham, 7 years ago

Resolution: invalid
Status: newclosed

This is expected behavior as per Spanning multi-valued relationships.

Note: See TracTickets for help on using tickets.
Back to Top