Opened 7 years ago

Closed 7 years ago

Last modified 3 years ago

#8283 closed (fixed)

.filter() is ignored after (query | query) construction

Reported by: dottedmag Owned by: mtredinnick
Component: Database layer (models, ORM) Version: master
Severity: Keywords:
Cc: piranha, benjixx Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

Model:

from django.db import models
from django.contrib.auth.models import User

class Asset(models.Model):
    public = models.BooleanField(default=True)
    owner = models.ForeignKey(User)

    def __unicode__(self):
        return "%s, %d (%s)" % (self.owner.username, self.id, "public" if self.public else "private")

Let's create several assets:

>>> from testqsbug.models import Asset
>>> from django.contrib.auth.models import User
>>> user1 = User.objects.get(username = "user1")
>>> user2 = User.objects.get(username = "user2")
>>> Asset.objects.create(public=True, owner=user1)
<Asset: user1, 1 (public)>
>>> Asset.objects.create(public=False, owner=user1)
<Asset: user1, 2 (private)>
>>> Asset.objects.create(public=True, owner=user2)
<Asset: user2, 3 (public)>
>>> Asset.objects.create(public=False, owner=user2)
<Asset: user2, 4 (private)>

Let's query all public assets OR assets that belong to some user:

>>> Asset.objects.filter(public=True) | Asset.objects.filter(owner=user1)
[<Asset: user1, 1 (public)>, <Asset: user1, 2 (private)>, <Asset: user2, 3 (public)>]

Let's filter from the result assets owned by user again (silly, I know):

>>> (Asset.objects.filter(public=True) | Asset.objects.filter(owner=user1)).filter(owner=user1)
[<Asset: user1, 1 (public)>, <Asset: user1, 2 (private)>, <Asset: user2, 3 (public)>]

Uhm. Does not work. Both requests resulted in the same query:

>>> q = (Asset.objects.filter(public=True) | Asset.objects.filter(owner=user1))
>>> print q.query
SELECT "testqsbug_asset"."id", "testqsbug_asset"."public", "testqsbug_asset"."owner_id" FROM "testqsbug_asset" WHERE ("testqsbug_asset"."public" = True  OR "testqsbug_asset"."owner_id" = 1 )
>>> q2 = (Asset.objects.filter(public=True) | Asset.objects.filter(owner=user1)).filter(owner=user1)
>>> print q2.query
SELECT "testqsbug_asset"."id", "testqsbug_asset"."public", "testqsbug_asset"."owner_id" FROM "testqsbug_asset" WHERE ("testqsbug_asset"."public" = True  OR "testqsbug_asset"."owner_id" = 1 )

Filtering by another user works fine:

>>> (Asset.objects.filter(public=True) | Asset.objects.filter(owner=user1)).filter(owner=user2)
[<Asset: user2, 3 (public)>]
>>> q3 = (Asset.objects.filter(public=True) | Asset.objects.filter(owner=user1)).filter(owner=user2)
>>> print q3.query
SELECT "testqsbug_asset"."id", "testqsbug_asset"."public", "testqsbug_asset"."owner_id" FROM "testqsbug_asset" WHERE (("testqsbug_asset"."public" = True  OR "testqsbug_asset"."owner_id" = 1 ) AND "testqsbug_asset"."owner_id" = 2 )

Change History (4)

comment:1 Changed 7 years ago by mtredinnick

  • milestone set to 1.0
  • Needs documentation unset
  • Needs tests unset
  • Owner changed from nobody to mtredinnick
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

comment:2 Changed 7 years ago by benjixx

  • Cc benjixx added

comment:3 Changed 7 years ago by mtredinnick

  • Resolution set to fixed
  • Status changed from new to closed

(In [8413]) Fixed #8283 -- Fixed an edge case when adding things to the "where" tree and
combining different connector types.

comment:4 Changed 3 years ago by jacob

  • milestone 1.0 deleted

Milestone 1.0 deleted

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