mirror of https://github.com/django/django.git
Fixed #26056 -- Added QuerySet.values()/values_list() support for ArrayField's __overlap lookup.
Thanks Mads Jensen and kosz85 and the initial patch.
This commit is contained in:
parent
81b1c167bf
commit
fbde929b19
|
@ -1,5 +1,6 @@
|
||||||
from django.db.models import Transform
|
from django.db.models import Transform
|
||||||
from django.db.models.lookups import PostgresOperatorLookup
|
from django.db.models.lookups import PostgresOperatorLookup
|
||||||
|
from django.db.models.sql.query import Query
|
||||||
|
|
||||||
from .search import SearchVector, SearchVectorExact, SearchVectorField
|
from .search import SearchVector, SearchVectorExact, SearchVectorField
|
||||||
|
|
||||||
|
@ -18,6 +19,13 @@ class Overlap(PostgresOperatorLookup):
|
||||||
lookup_name = "overlap"
|
lookup_name = "overlap"
|
||||||
postgres_operator = "&&"
|
postgres_operator = "&&"
|
||||||
|
|
||||||
|
def get_prep_lookup(self):
|
||||||
|
from .expressions import ArraySubquery
|
||||||
|
|
||||||
|
if isinstance(self.rhs, Query):
|
||||||
|
self.rhs = ArraySubquery(self.rhs)
|
||||||
|
return super().get_prep_lookup()
|
||||||
|
|
||||||
|
|
||||||
class HasKey(PostgresOperatorLookup):
|
class HasKey(PostgresOperatorLookup):
|
||||||
lookup_name = "has_key"
|
lookup_name = "has_key"
|
||||||
|
|
|
@ -170,7 +170,7 @@ Returns objects where the data shares any results with the values passed. Uses
|
||||||
the SQL operator ``&&``. For example::
|
the SQL operator ``&&``. For example::
|
||||||
|
|
||||||
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
|
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
|
||||||
>>> Post.objects.create(name='Second post', tags=['thoughts'])
|
>>> Post.objects.create(name='Second post', tags=['thoughts', 'tutorial'])
|
||||||
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])
|
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])
|
||||||
|
|
||||||
>>> Post.objects.filter(tags__overlap=['thoughts'])
|
>>> Post.objects.filter(tags__overlap=['thoughts'])
|
||||||
|
@ -179,6 +179,14 @@ the SQL operator ``&&``. For example::
|
||||||
>>> Post.objects.filter(tags__overlap=['thoughts', 'tutorial'])
|
>>> Post.objects.filter(tags__overlap=['thoughts', 'tutorial'])
|
||||||
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
|
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
|
||||||
|
|
||||||
|
>>> Post.objects.filter(tags__overlap=Post.objects.values_list('tags'))
|
||||||
|
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
|
||||||
|
|
||||||
|
.. versionchanged:: 4.2
|
||||||
|
|
||||||
|
Support for ``QuerySet.values()`` and ``values_list()`` as a right-hand
|
||||||
|
side was added.
|
||||||
|
|
||||||
.. fieldlookup:: arrayfield.len
|
.. fieldlookup:: arrayfield.len
|
||||||
|
|
||||||
``len``
|
``len``
|
||||||
|
|
|
@ -102,6 +102,9 @@ Minor features
|
||||||
<django.contrib.postgres.search.TrigramStrictWordDistance>` expressions allow
|
<django.contrib.postgres.search.TrigramStrictWordDistance>` expressions allow
|
||||||
using trigram strict word similarity.
|
using trigram strict word similarity.
|
||||||
|
|
||||||
|
* The :lookup:`arrayfield.overlap` lookup now supports ``QuerySet.values()``
|
||||||
|
and ``values_list()`` as a right-hand side.
|
||||||
|
|
||||||
:mod:`django.contrib.redirects`
|
:mod:`django.contrib.redirects`
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -414,6 +414,21 @@ class TestQuerying(PostgreSQLTestCase):
|
||||||
[obj_1, obj_2],
|
[obj_1, obj_2],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_overlap_values(self):
|
||||||
|
qs = NullableIntegerArrayModel.objects.filter(order__lt=3)
|
||||||
|
self.assertCountEqual(
|
||||||
|
NullableIntegerArrayModel.objects.filter(
|
||||||
|
field__overlap=qs.values_list("field"),
|
||||||
|
),
|
||||||
|
self.objs[:3],
|
||||||
|
)
|
||||||
|
self.assertCountEqual(
|
||||||
|
NullableIntegerArrayModel.objects.filter(
|
||||||
|
field__overlap=qs.values("field"),
|
||||||
|
),
|
||||||
|
self.objs[:3],
|
||||||
|
)
|
||||||
|
|
||||||
def test_lookups_autofield_array(self):
|
def test_lookups_autofield_array(self):
|
||||||
qs = (
|
qs = (
|
||||||
NullableIntegerArrayModel.objects.filter(
|
NullableIntegerArrayModel.objects.filter(
|
||||||
|
|
Loading…
Reference in New Issue