Refs #27834 -- Removed Value wrapping from StrIndex's substring param.
This commit is contained in:
parent
7170820b4e
commit
7f8a924b45
|
@ -196,15 +196,12 @@ class StrIndex(Func):
|
||||||
function = 'INSTR'
|
function = 'INSTR'
|
||||||
arity = 2
|
arity = 2
|
||||||
|
|
||||||
def __init__(self, expression, substring, **extra):
|
def __init__(self, string, substring, **extra):
|
||||||
"""
|
"""
|
||||||
expression: the name of a field, or an expression returning a string
|
string: the name of a field, or an expression returning a string
|
||||||
substring: a string to find inside expression
|
substring: the name of a field, or an expression returning a string
|
||||||
"""
|
"""
|
||||||
if not hasattr(substring, 'resolve_expression'):
|
super().__init__(string, substring, output_field=fields.IntegerField(), **extra)
|
||||||
substring = Value(substring)
|
|
||||||
expressions = [expression, substring]
|
|
||||||
super().__init__(*expressions, output_field=fields.IntegerField(), **extra)
|
|
||||||
|
|
||||||
def as_postgresql(self, compiler, connection):
|
def as_postgresql(self, compiler, connection):
|
||||||
return super().as_sql(compiler, connection, function='STRPOS')
|
return super().as_sql(compiler, connection, function='STRPOS')
|
||||||
|
|
|
@ -240,26 +240,29 @@ Usage example::
|
||||||
``StrIndex``
|
``StrIndex``
|
||||||
============
|
============
|
||||||
|
|
||||||
.. class:: StrIndex(expression, substring, **extra)
|
.. class:: StrIndex(string, substring, **extra)
|
||||||
|
|
||||||
.. versionadded:: 2.0
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
Returns a positive integer corresponding to the 1-indexed position of the
|
Returns a positive integer corresponding to the 1-indexed position of the first
|
||||||
first occurrence of ``substring`` inside another string, or 0 if the substring
|
occurrence of ``substring`` inside ``string``, or 0 if ``substring`` is not
|
||||||
is not found.
|
found.
|
||||||
|
|
||||||
Usage example::
|
Usage example::
|
||||||
|
|
||||||
|
>>> from django.db.models import Value as V
|
||||||
>>> from django.db.models.functions import StrIndex
|
>>> from django.db.models.functions import StrIndex
|
||||||
>>> Author.objects.create(name='Margaret Smith')
|
>>> Author.objects.create(name='Margaret Smith')
|
||||||
>>> Author.objects.create(name='Smith, Margaret')
|
>>> Author.objects.create(name='Smith, Margaret')
|
||||||
>>> Author.objects.create(name='Margaret Jackson')
|
>>> Author.objects.create(name='Margaret Jackson')
|
||||||
>>> authors = Author.objects.annotate(
|
>>> authors = Author.objects.annotate(
|
||||||
... smith_index=StrIndex('name', 'Smith')).order_by('smith_index')
|
... smith_index=StrIndex('name', V('Smith'))
|
||||||
|
... ).order_by('smith_index')
|
||||||
>>> authors.first().smith_index
|
>>> authors.first().smith_index
|
||||||
0
|
0
|
||||||
>>> authors = Author.objects.annotate(
|
>>> authors = Author.objects.annotate(
|
||||||
... smith_index=StrIndex('name', 'Smith')).filter(smith_index__gt=0)
|
... smith_index=StrIndex('name', V('Smith'))
|
||||||
|
... ).filter(smith_index__gt=0)
|
||||||
<QuerySet [<Author: Margaret Smith>, <Author: Smith, Margaret>]>
|
<QuerySet [<Author: Margaret Smith>, <Author: Smith, Margaret>]>
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from django.db.models import Value
|
||||||
from django.db.models.functions import StrIndex
|
from django.db.models.functions import StrIndex
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
@ -10,13 +11,13 @@ class StrIndexTests(TestCase):
|
||||||
Author.objects.create(name='George. R. R. Martin')
|
Author.objects.create(name='George. R. R. Martin')
|
||||||
Author.objects.create(name='J. R. R. Tolkien')
|
Author.objects.create(name='J. R. R. Tolkien')
|
||||||
Author.objects.create(name='Terry Pratchett')
|
Author.objects.create(name='Terry Pratchett')
|
||||||
authors = Author.objects.annotate(fullstop=StrIndex('name', 'R.'))
|
authors = Author.objects.annotate(fullstop=StrIndex('name', Value('R.')))
|
||||||
self.assertQuerysetEqual(authors.order_by('name'), [9, 4, 0], lambda a: a.fullstop)
|
self.assertQuerysetEqual(authors.order_by('name'), [9, 4, 0], lambda a: a.fullstop)
|
||||||
|
|
||||||
def test_annotate_textfield(self):
|
def test_annotate_textfield(self):
|
||||||
Article.objects.create(
|
Article.objects.create(
|
||||||
title='How to Django',
|
title='How to Django',
|
||||||
text='Lorem ipsum dolor sit amet.',
|
text='This is about How to Django.',
|
||||||
written=timezone.now(),
|
written=timezone.now(),
|
||||||
)
|
)
|
||||||
Article.objects.create(
|
Article.objects.create(
|
||||||
|
@ -24,15 +25,15 @@ class StrIndexTests(TestCase):
|
||||||
text="Won't find anything here.",
|
text="Won't find anything here.",
|
||||||
written=timezone.now(),
|
written=timezone.now(),
|
||||||
)
|
)
|
||||||
articles = Article.objects.annotate(ipsum_index=StrIndex('text', 'ipsum'))
|
articles = Article.objects.annotate(title_pos=StrIndex('text', 'title'))
|
||||||
self.assertQuerysetEqual(articles.order_by('title'), [7, 0], lambda a: a.ipsum_index)
|
self.assertQuerysetEqual(articles.order_by('title'), [15, 0], lambda a: a.title_pos)
|
||||||
|
|
||||||
def test_order_by(self):
|
def test_order_by(self):
|
||||||
Author.objects.create(name='Terry Pratchett')
|
Author.objects.create(name='Terry Pratchett')
|
||||||
Author.objects.create(name='J. R. R. Tolkien')
|
Author.objects.create(name='J. R. R. Tolkien')
|
||||||
Author.objects.create(name='George. R. R. Martin')
|
Author.objects.create(name='George. R. R. Martin')
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Author.objects.order_by(StrIndex('name', 'R.').asc()), [
|
Author.objects.order_by(StrIndex('name', Value('R.')).asc()), [
|
||||||
'Terry Pratchett',
|
'Terry Pratchett',
|
||||||
'J. R. R. Tolkien',
|
'J. R. R. Tolkien',
|
||||||
'George. R. R. Martin',
|
'George. R. R. Martin',
|
||||||
|
@ -40,7 +41,7 @@ class StrIndexTests(TestCase):
|
||||||
lambda a: a.name
|
lambda a: a.name
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Author.objects.order_by(StrIndex('name', 'R.').desc()), [
|
Author.objects.order_by(StrIndex('name', Value('R.')).desc()), [
|
||||||
'George. R. R. Martin',
|
'George. R. R. Martin',
|
||||||
'J. R. R. Tolkien',
|
'J. R. R. Tolkien',
|
||||||
'Terry Pratchett',
|
'Terry Pratchett',
|
||||||
|
@ -52,14 +53,14 @@ class StrIndexTests(TestCase):
|
||||||
Author.objects.create(name='ツリー')
|
Author.objects.create(name='ツリー')
|
||||||
Author.objects.create(name='皇帝')
|
Author.objects.create(name='皇帝')
|
||||||
Author.objects.create(name='皇帝 ツリー')
|
Author.objects.create(name='皇帝 ツリー')
|
||||||
authors = Author.objects.annotate(sb=StrIndex('name', 'リ'))
|
authors = Author.objects.annotate(sb=StrIndex('name', Value('リ')))
|
||||||
self.assertQuerysetEqual(authors.order_by('name'), [2, 0, 5], lambda a: a.sb)
|
self.assertQuerysetEqual(authors.order_by('name'), [2, 0, 5], lambda a: a.sb)
|
||||||
|
|
||||||
def test_filtering(self):
|
def test_filtering(self):
|
||||||
Author.objects.create(name='George. R. R. Martin')
|
Author.objects.create(name='George. R. R. Martin')
|
||||||
Author.objects.create(name='Terry Pratchett')
|
Author.objects.create(name='Terry Pratchett')
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Author.objects.annotate(middle_name=StrIndex('name', 'R.')).filter(middle_name__gt=0),
|
Author.objects.annotate(middle_name=StrIndex('name', Value('R.'))).filter(middle_name__gt=0),
|
||||||
['George. R. R. Martin'],
|
['George. R. R. Martin'],
|
||||||
lambda a: a.name
|
lambda a: a.name
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue