Spec-Zone.ru › Django 1.9

Функции базы данных

Классы, описанные ниже, предоставляют пользователям способ использования функций, предоставляемых базовой базой данных, как аннотации, агрегации или фильтры в 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/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API