Функции базы данных
Классы, описанные ниже, предоставляют пользователям способ использования функций, предоставляемых базовой базой данных, как аннотации, агрегации или фильтры в Django. Функции также являются выражениями, поэтому их можно использовать и комбинировать с другими выражениями, такими как функции агрегации.
В примерах каждой функции мы будем использовать следующую модель:
class Author(models.Model):
name = models.CharField(max_length=50)
age = models.PositiveIntegerField(null=True, blank=True)
alias = models.CharField(max_length=50, null=True, blank=True)
goes_by = models.CharField(max_length=50, null=True, blank=True)
Обычно мы не рекомендуем разрешать null=True для CharField, так как это позволяет полю иметь два «пустых значения», но это важно для примера Coalesce ниже.
Coalesce
-
class Coalesce(*expressions, **extra)[source]
Принимает список из как минимум двух имён полей или выражений и возвращает первое не-нулевое значение (обратите внимание, что пустая строка не считается нулевым значением). Каждый аргумент должен быть одного типа, поэтому смешение текста и чисел приведёт к ошибке базы данных.
Примеры использования:
>>> # Get a screen name from least to most public
>>> from django.db.models import Sum, Value as V
>>> from django.db.models.functions import Coalesce
>>> Author.objects.create(name='Margaret Smith', goes_by='Maggie')
>>> author = Author.objects.annotate(
... screen_name=Coalesce('alias', 'goes_by', 'name')).get()
>>> print(author.screen_name)
Maggie
>>> # Prevent an aggregate Sum() from returning None
>>> aggregated = Author.objects.aggregate(
... combined_age=Coalesce(Sum('age'), V(0)),
... combined_age_default=Sum('age'))
>>> print(aggregated['combined_age'])
0
>>> print(aggregated['combined_age_default'])
None
Предупреждение
Значение Python, переданное в Coalesce в MySQL, может быть преобразовано в неверный тип, если его явно не привести к правильному типу базы данных:
>>> from django.db.models.expressions import RawSQL
>>> from django.utils import timezone
>>> now = timezone.now()
>>> now_sql = RawSQL("cast(%s as datetime)", (now,))
>>> Coalesce('updated', now_sql)
Concat
-
class Concat(*expressions, **extra)[source]
Принимает список из как минимум двух текстовых полей или выражений и возвращает конкатенированный текст. Каждый аргумент должен быть текстового или символьного типа. Если вы хотите конкатенировать TextField() со CharField(), убедитесь, что вы указали Django, что output_field должен быть TextField(). Это также необходимо при конкатенации Value, как показано в примере ниже.
Эта функция никогда не вернёт нулевое значение. В тех бэкендах, где нулевой аргумент приводит к тому, что всё выражение становится нулевым, Django будет гарантировать, что каждый нулевой фрагмент преобразуется в пустую строку сначала.
Пример использования:
>>> # Get the display name as "name (goes_by)"
>>> from django.db.models import CharField, Value as V
>>> from django.db.models.functions import Concat
>>> Author.objects.create(name='Margaret Smith', goes_by='Maggie')
>>> author = Author.objects.annotate(
... screen_name=Concat('name', V(' ('), 'goes_by', V(')'),
... output_field=CharField())).get()
>>> print(author.screen_name)
Margaret Smith (Maggie)
Greatest
-
class Greatest(*expressions, **extra)[source]
Принимает список из как минимум двух имён полей или выражений и возвращает наибольшее значение. Каждый аргумент должен быть одного типа, поэтому смешение текста и чисел приведёт к ошибке базы данных.
Пример использования:
class Blog(models.Model):
body = models.TextField()
modified = models.DateTimeField(auto_now=True)
class Comment(models.Model):
body = models.TextField()
modified = models.DateTimeField(auto_now=True)
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
>>> from django.db.models.functions import Greatest
>>> blog = Blog.objects.create(body='Greatest is the best.')
>>> comment = Comment.objects.create(body='No, Least is better.', blog=blog)
>>> comments = Comment.objects.annotate(last_updated=Greatest('modified', 'blog__modified'))
>>> annotated_comment = comments.get()
annotated_comment.last_updated будет самым последним из blog.modified и comment.modified.
Предупреждение
Поведение Greatest когда одно или несколько выражений могут быть null различается в разных базах данных:
- PostgreSQL:
Greatestвернёт наибольшее не-нулевое выражение илиnull, если все выражения являютсяnull. - SQLite, Oracle и MySQL: Если какое-либо выражение является
null,Greatestвернётnull.
Поведение PostgreSQL можно смоделировать, используя Coalesce, если вы знаете разумное минимальное значение в качестве значения по умолчанию.
Least
-
class Least(*expressions, **extra)[source]
Принимает список из как минимум двух имён полей или выражений и возвращает наименьшее значение. Каждый аргумент должен быть одного типа, поэтому смешение текста и чисел приведёт к ошибке базы данных.
Предупреждение
Поведение Least когда одно или несколько выражений могут быть null различается в разных базах данных:
- PostgreSQL:
Leastвернёт наименьшее не-нулевое выражение илиnull, если все выражения являютсяnull. - SQLite, Oracle и MySQL: Если какое-либо выражение является
null,Leastвернётnull.
Поведение PostgreSQL можно смоделировать, используя Coalesce, если вы знаете разумное максимальное значение в качестве значения по умолчанию.
Length
-
class Length(expression, **extra)[source]
Принимает одно текстовое поле или выражение и возвращает количество символов в значении. Если выражение является нулевым, длина также будет нулевой.
Пример использования:
>>> # Get the length of the name and goes_by fields
>>> from django.db.models.functions import Length
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(
... name_length=Length('name'),
... goes_by_length=Length('goes_by')).get()
>>> print(author.name_length, author.goes_by_length)
(14, None)
Его также можно зарегистрировать как преобразование. Например:
>>> from django.db.models import CharField >>> from django.db.models.functions import Length >>> CharField.register_lookup(Length, 'length') >>> # Get authors whose name is longer than 7 characters >>> authors = Author.objects.filter(name__length__gt=7)
Добавлена возможность регистрации функции в качестве преобразования.
Lower
-
class Lower(expression, **extra)[source]
Принимает одно текстовое поле или выражение и возвращает представление в нижнем регистре.
Его также можно зарегистрировать как преобразование, как описано в Length.
Пример использования:
>>> from django.db.models.functions import Lower
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(name_lower=Lower('name')).get()
>>> print(author.name_lower)
margaret smith
Добавлена возможность регистрации функции в качестве преобразования.
Now
-
class Now[source]
Возвращает текущую дату и время сервера базы данных во время выполнения запроса, обычно используя SQL CURRENT_TIMESTAMP.
Пример использования:
>>> from django.db.models.functions import Now >>> Article.objects.filter(published__lte=Now()) [<Article: How to Django>]
Учитывая PostgreSQL
В PostgreSQL SQL CURRENT_TIMESTAMP возвращает время начала текущей транзакции. Поэтому для кросс-базовой совместимости Now() использует STATEMENT_TIMESTAMP вместо этого. Если вам нужно время отметки транзакции, используйте django.contrib.postgres.functions.TransactionNow.
Substr
-
class Substr(expression, pos, length=None, **extra)[source]
Возвращает подстроку длины length из поля или выражения, начиная с позиции pos . Позиция индексируется с 1, поэтому позиция должна быть больше 0. Если length является None, возвращается остальная часть строки.
Пример использования:
>>> # Set the alias to the first 5 characters of the name as lowercase
>>> from django.db.models.functions import Substr, Lower
>>> Author.objects.create(name='Margaret Smith')
>>> Author.objects.update(alias=Lower(Substr('name', 1, 5)))
1
>>> print(Author.objects.get(name='Margaret Smith').alias)
marga
Upper
-
class Upper(expression, **extra)[source]
Принимает одно текстовое поле или выражение и возвращает представление в верхнем регистре.
Его также можно зарегистрировать как преобразование, как описано в Length.
Пример использования:
>>> from django.db.models.functions import Upper
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(name_upper=Upper('name')).get()
>>> print(author.name_upper)
MARGARET SMITH
Добавлена возможность регистрации функции в качестве преобразования.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/1.9/ref/models/database-functions/