#32068 closed Cleanup/optimization (fixed)

Raise a descriptive error on get() with filters operation following QuerySet.union(), intersection(), and difference().

Reported by: Timo Ludwig Owned by: Hasan Ramezani
Component: Database layer (models, ORM) Version: 3.1
Severity: Normal Keywords: queryset, difference
Cc: Hasan Ramezani Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

The QuerySet resulting from q1.difference(q2) does not allow to retrieve one specific object of that resulting QuerySet.

Minimal example:

models.py

from django.db import models

class Test(models.Model):
    name = models.CharField(max_length=30)

python manage.py shell

>>> from test.models import Test
>>> qs1 = Test.objects.all()
>>> qs1
<QuerySet [<Test: Test object (1)>, <Test: Test object (2)>, <Test: Test object (3)>]>
>>> qs2 = Test.objects.filter(id=1)
>>> qs2
<QuerySet [<Test: Test object (1)>]>
>>> qs3 = qs1.difference(qs2)
>>> qs3
<QuerySet [<Test: Test object (2)>, <Test: Test object (3)>]>
>>> qs3.get(id=2)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/lib/python3.8/site-packages/django/db/models/query.py", line 433, in get
    raise self.model.MultipleObjectsReturned(
test.models.Test.MultipleObjectsReturned: get() returned more than one Test -- it returned 2!

Django version: 3.1.2
Python version: 3.8.5
OS: Arch Linux

I also experienced this in the regular request/view-context, with other Django versions (2.2) and other python versions (3.7).
Sorry if this is the expected behavior, a known bug or if I missed something which changes the behavior only on my system.
If you need more information, I'll be happy to assist.

Change History (5)

comment:1 Changed 23 months ago by Mariusz Felisiak

Cc: Hasan Ramezani added
Easy pickings: set
Summary: QuerySet.difference() results in QuerySet.get(**kwargs) ignoring kwargs.Raise a descriptive error on get() with filters operation following QuerySet.union(), intersection(), and difference().
Triage Stage: UnreviewedAccepted
Type: BugCleanup/optimization

get() with filters is unsupported, see documentation:

In addition, only LIMIT, OFFSET, COUNT(*), ORDER BY, and specifying columns (i.e. slicing, count(), order_by(), and values()/values_list()) are allowed on the resulting QuerySet.

but I agree that we should raise a descriptive error for get(...) (see related #27995, #31148).

comment:2 Changed 23 months ago by Hasan Ramezani

Owner: changed from nobody to Hasan Ramezani
Status: newassigned

comment:3 Changed 23 months ago by Hasan Ramezani

Has patch: set

comment:4 Changed 23 months ago by Mariusz Felisiak <felisiak.mariusz@…>

In 7cfa40d:

Refs #32068 -- Added tests for get() following union(), intersection(), and difference().

comment:5 Changed 23 months ago by Mariusz Felisiak <felisiak.mariusz@…>

Resolution: fixed
Status: assignedclosed

In 981a3426:

Fixed #32068 -- Added error messages on get() with filters following union(), intersection(), and difference().

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