瀏覽代碼

Refs #27834 -- Removed Value wrapping from StrIndex's substring param.

Adam Johnson 8 年之前
父節點
當前提交
7f8a924b45
共有 3 個文件被更改,包括 22 次插入21 次删除
  1. 4 7
      django/db/models/functions/base.py
  2. 9 6
      docs/ref/models/database-functions.txt
  3. 9 8
      tests/db_functions/test_strindex.py

+ 4 - 7
django/db/models/functions/base.py

@@ -196,15 +196,12 @@ class StrIndex(Func):
     function = 'INSTR'
     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
-        substring: a string to find inside expression
+        string: the name of a field, or an expression returning a string
+        substring: the name of a field, or an expression returning a string
         """
-        if not hasattr(substring, 'resolve_expression'):
-            substring = Value(substring)
-        expressions = [expression, substring]
-        super().__init__(*expressions, output_field=fields.IntegerField(), **extra)
+        super().__init__(string, substring, output_field=fields.IntegerField(), **extra)
 
     def as_postgresql(self, compiler, connection):
         return super().as_sql(compiler, connection, function='STRPOS')

+ 9 - 6
docs/ref/models/database-functions.txt

@@ -240,26 +240,29 @@ Usage example::
 ``StrIndex``
 ============
 
-.. class:: StrIndex(expression, substring, **extra)
+.. class:: StrIndex(string, substring, **extra)
 
 .. versionadded:: 2.0
 
-Returns a positive integer corresponding to the 1-indexed position of the
-first occurrence of ``substring`` inside another string, or 0 if the substring
-is not found.
+Returns a positive integer corresponding to the 1-indexed position of the first
+occurrence of ``substring`` inside ``string``, or 0 if ``substring`` is not
+found.
 
 Usage example::
 
+    >>> from django.db.models import Value as V
     >>> from django.db.models.functions import StrIndex
     >>> Author.objects.create(name='Margaret Smith')
     >>> Author.objects.create(name='Smith, Margaret')
     >>> Author.objects.create(name='Margaret Jackson')
     >>> 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
     0
     >>> 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>]>
 
 .. warning::

+ 9 - 8
tests/db_functions/test_strindex.py

@@ -1,3 +1,4 @@
+from django.db.models import Value
 from django.db.models.functions import StrIndex
 from django.test import TestCase
 from django.utils import timezone
@@ -10,13 +11,13 @@ class StrIndexTests(TestCase):
         Author.objects.create(name='George. R. R. Martin')
         Author.objects.create(name='J. R. R. Tolkien')
         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)
 
     def test_annotate_textfield(self):
         Article.objects.create(
             title='How to Django',
-            text='Lorem ipsum dolor sit amet.',
+            text='This is about How to Django.',
             written=timezone.now(),
         )
         Article.objects.create(
@@ -24,15 +25,15 @@ class StrIndexTests(TestCase):
             text="Won't find anything here.",
             written=timezone.now(),
         )
-        articles = Article.objects.annotate(ipsum_index=StrIndex('text', 'ipsum'))
-        self.assertQuerysetEqual(articles.order_by('title'), [7, 0], lambda a: a.ipsum_index)
+        articles = Article.objects.annotate(title_pos=StrIndex('text', 'title'))
+        self.assertQuerysetEqual(articles.order_by('title'), [15, 0], lambda a: a.title_pos)
 
     def test_order_by(self):
         Author.objects.create(name='Terry Pratchett')
         Author.objects.create(name='J. R. R. Tolkien')
         Author.objects.create(name='George. R. R. Martin')
         self.assertQuerysetEqual(
-            Author.objects.order_by(StrIndex('name', 'R.').asc()), [
+            Author.objects.order_by(StrIndex('name', Value('R.')).asc()), [
                 'Terry Pratchett',
                 'J. R. R. Tolkien',
                 'George. R. R. Martin',
@@ -40,7 +41,7 @@ class StrIndexTests(TestCase):
             lambda a: a.name
         )
         self.assertQuerysetEqual(
-            Author.objects.order_by(StrIndex('name', 'R.').desc()), [
+            Author.objects.order_by(StrIndex('name', Value('R.')).desc()), [
                 'George. R. R. Martin',
                 'J. R. R. Tolkien',
                 'Terry Pratchett',
@@ -52,14 +53,14 @@ class StrIndexTests(TestCase):
         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)
 
     def test_filtering(self):
         Author.objects.create(name='George. R. R. Martin')
         Author.objects.create(name='Terry Pratchett')
         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'],
             lambda a: a.name
         )