Fonctions de base de données¶
Les classes documentĂ©es ci-dessous permettent dâexploiter dans Django les fonctions fournies par la base de donnĂ©es sous-jacente telles que les annotations, les agrĂ©gations ou les filtres. Les fonctions sont Ă©galement des expressions, elles peuvent donc ĂȘtre utilisĂ©es et combinĂ©es avec dâautres expressions comme les fonctions dâagrĂ©gation.
Nous allons utiliser le modĂšle suivant dans les exemples de chaque fonction :
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)
Nous ne recommandons généralement pas de définir null=True
pour les champs CharField
car cela permet au champ de possĂ©der deux valeurs « vides » diffĂ©rentes, mais nous lâutilisons ici pour lâexemple Coalesce
ci-dessous.
Fonctions de comparaison et de conversion¶
Cast
¶
-
class
Cast
(expression, output_field)¶
Force le type de résultat de expression
Ă celui de output_field
.
Exemple dâutilisation :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Cast
>>> Author.objects.create(age=25, name='Margaret Smith')
>>> author = Author.objects.annotate(
... age_as_float=Cast('age', output_field=FloatField()),
... ).get()
>>> print(author.age_as_float)
25.0
Coalesce
¶
-
class
Coalesce
(*expressions, **extra)¶
Accepte une liste dâau moins deux noms de champ ou expressions et renvoie la premiĂšre valeur non nulle (notez quâune chaĂźne vide nâest pas considĂ©rĂ©e comme une valeur nulle). Chaque paramĂštre doit ĂȘtre dâun type similaire ; si vous mĂ©langez des textes et des nombres, la base de donnĂ©es produira une erreur.
Exemples dâutilisation :
>>> # 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
Avertissement
Avec MySQL, il est possible quâune valeur Python transmise Ă Coalesce
soit convertie en un type incorrect, sauf dans le cas oĂč le bon type de base de donnĂ©es est explicitement forcĂ© :
>>> from django.db.models import DateTimeField
>>> from django.db.models.functions import Cast, Coalesce
>>> from django.utils import timezone
>>> now = timezone.now()
>>> Coalesce('updated', Cast(now, DateTimeField()))
Greatest
¶
-
class
Greatest
(*expressions, **extra)¶
Accepte une liste dâau moins deux noms de champ ou expressions et renvoie la plus grande valeur. Chaque paramĂštre doit ĂȘtre dâun type similaire ; si vous mĂ©langez des textes et des nombres, la base de donnĂ©es produira une erreur.
Exemple dâutilisation :
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
sera la valeur la plus récente entre blog.modified
et comment.modified
.
Avertissement
Le comportement de Greatest
varie entre les bases de donnĂ©es lorsquâune ou plusieurs des expressions ont la valeur null
:
- PostgreSQL :
Greatest
renvoie lâexpression non nulle la plus grande, ounull
si toutes les expressions valentnull
. - SQLite, Oracle et MySQL : si lâune des expressions vaut
null
,Greatest
renvoienull
.
Le comportement de PostgreSQL peut ĂȘtre Ă©mulĂ© Ă lâaide de Coalesce
si vous avez une valeur minimum adéquate à fournir comme valeur par défaut.
Least
¶
-
class
Least
(*expressions, **extra)¶
Accepte une liste dâau moins deux noms de champ ou expressions et renvoie la plus petite valeur. Chaque paramĂštre doit ĂȘtre dâun type similaire ; si vous mĂ©langez des textes et des nombres, la base de donnĂ©es produira une erreur.
Avertissement
Le comportement de Least
varie entre les bases de donnĂ©es lorsquâune ou plusieurs des expressions ont la valeur null
:
- PostgreSQL :
Least
renvoie lâexpression non nulle la plus petite, ounull
si toutes les expressions valentnull
. - SQLite, Oracle et MySQL : si lâune des expressions vaut
null
,Least
renvoienull
.
Le comportement de PostgreSQL peut ĂȘtre Ă©mulĂ© Ă lâaide de Coalesce
si vous avez une valeur maximum adéquate à fournir comme valeur par défaut.
NullIf
¶
-
class
NullIf
(expression1, expression2)¶
Accepte deux expressions et renvoie None
si elles sont égales, sinon renvoie expression1
.
Avertissement pour Oracle
En raison dâune convention Oracle, cette fonction renvoie la chaĂźne vide au lieu de None
lorsque les expressions sont de type CharField
.
La transmission de Value(None)
Ă expression1
est interdite avec Oracle car cette base de donnĂ©es nâaccepte pas NULL
comme premier paramĂštre.
Fonctions de date¶
Nous allons utiliser le modĂšle suivant dans les exemples de chaque fonction :
class Experiment(models.Model):
start_datetime = models.DateTimeField()
start_date = models.DateField(null=True, blank=True)
start_time = models.TimeField(null=True, blank=True)
end_datetime = models.DateTimeField(null=True, blank=True)
end_date = models.DateField(null=True, blank=True)
end_time = models.TimeField(null=True, blank=True)
Extract
¶
-
class
Extract
(expression, lookup_name=None, tzinfo=None, **extra)¶
Extrait un composant de date sous forme de nombre.
Accepte une expression
représentant un champ DateField
, DateTimeField
, TimeField
ou DurationField
ainsi quâun nom dâexpression lookup_name
, et renvoie la partie de date référencée par lookup_name
sous forme de champ IntegerField
. Django utilise habituellement la fonction dâextraction des bases de donnĂ©es, il est donc possible dâutiliser nâimporte quel nom lookup_name
pris en charge par la base de données en cours. Il est possible de passer aussi une sous-classe de tzinfo
, habituellement fournie par pytz
, pour extraire une valeur dans un fuseau horaire spécifique.
Ătant donnĂ©e la date/heure 2015-06-15 23:30:01.000321+00:00
, les valeurs lookup_name
possibles renvoient :
- « year » (année) : 2015
- « iso_year » (année ISO) : 2015
- « quarter »: 2
- « month » (mois) : 6
- « day » (jour) : 15
- « week »: 25
- « week_day » (jour de semaine) : 2
- « iso_week_day »: 1
- « hour » (heure) : 23
- « minute »: 30
- « second »: 1
Si un fuseau horaire différent comme Australia/Melbourne
est actif dans Django, la date/heure est convertie dans le fuseau avant que la valeur soit extraite. Le dĂ©calage horaire de Melbourne dans la date dâexemple ci-dessus est +10:00. Les valeurs renvoyĂ©es lorsque ce fuseau est actif seront les mĂȘmes que ci-dessus, Ă lâexception de :
- « day »: 16
- « week_day »: 3
- « iso_week_day »: 2
- « hour »: 9
Valeurs week_day
Lâextraction week_day
est calculée différemment de la plupart des bases de données et des fonctions Python standards. Cette fonction renvoie 1
pour dimanche, 2
pour lundi, jusquâĂ 7
pour samedi.
Le calcul équivalent en Python est :
>>> from datetime import datetime
>>> dt = datetime(2015, 6, 15)
>>> (dt.isoweekday() % 7) + 1
2
Valeurs week
Lâexpression de recherche week
est calculĂ©e sur la base du standard ISO-8601, câest-Ă -dire quâune semaine commence un lundi. La premiĂšre semaine dâune annĂ©e est celle qui contient le premier jeudi de lâannĂ©e, câest-Ă -dire que la premiĂšre semaine Ă sa majoritĂ© (4 ou plus) de jours dans lâannĂ©e. La valeur renvoyĂ©e se situe dans lâintervalle 1 Ă 52 ou 53.
Chaque valeur lookup_name
ci-dessus possĂšde une sous-classe de Extract
correspondante (Ă©numĂ©rĂ©es ci-dessous) qui devrait ĂȘtre utilisĂ©e au lieu de lâĂ©quivalent plus bavard, câest-Ă -dire ExtractYear(...)
au lieu de Extract(..., lookup_name='year')
.
Exemple dâutilisation :
>>> from datetime import datetime
>>> from django.db.models.functions import Extract
>>> start = datetime(2015, 6, 15)
>>> end = datetime(2015, 7, 2)
>>> Experiment.objects.create(
... start_datetime=start, start_date=start.date(),
... end_datetime=end, end_date=end.date())
>>> # Add the experiment start year as a field in the QuerySet.
>>> experiment = Experiment.objects.annotate(
... start_year=Extract('start_datetime', 'year')).get()
>>> experiment.start_year
2015
>>> # How many experiments completed in the same year in which they started?
>>> Experiment.objects.filter(
... start_datetime__year=Extract('end_datetime', 'year')).count()
1
Extractions DateField
¶
-
class
ExtractYear
(expression, tzinfo=None, **extra)¶ -
lookup_name = 'year'
-
-
class
ExtractIsoYear
(expression, tzinfo=None, **extra)¶ Renvoie lâannĂ©e avec numĂ©ro de semaine selon ISO-8601.
-
lookup_name = 'iso_year'
-
-
class
ExtractMonth
(expression, tzinfo=None, **extra)¶ -
lookup_name = 'month'
-
-
class
ExtractDay
(expression, tzinfo=None, **extra)¶ -
lookup_name = 'day'
-
-
class
ExtractWeekDay
(expression, tzinfo=None, **extra)¶ -
lookup_name = 'week_day'
-
-
class
ExtractIsoWeekDay
(expression, tzinfo=None, **extra)¶ - New in Django 3.1.
Renvoie le jour de la semaine ISO-8601, le jour 1 étant un lundi et le jour 7 un dimanche.
-
lookup_name = 'iso_week_day'
-
-
class
ExtractWeek
(expression, tzinfo=None, **extra)¶ -
lookup_name = 'week'
-
-
class
ExtractQuarter
(expression, tzinfo=None, **extra)¶ -
lookup_name = 'quarter'
-
Il sâagit dâĂ©quivalents logiques Ă Extract('champ_date', lookup_name)
. Chaque classe est aussi une classe Transform
inscrite pour les champs DateField
et DateTimeField
comme __(lookup_name)
, par ex. __year
.
Comme les champs DateField
nâont pas de composant dâheure, seules les sous-classes de Extract
qui sâappliquent aux parties de date peuvent ĂȘtre utilisĂ©es avec DateField
:
>>> from datetime import datetime
>>> from django.utils import timezone
>>> from django.db.models.functions import (
... ExtractDay, ExtractMonth, ExtractQuarter, ExtractWeek,
... ExtractIsoWeekDay, ExtractWeekDay, ExtractIsoYear, ExtractYear,
... )
>>> start_2015 = datetime(2015, 6, 15, 23, 30, 1, tzinfo=timezone.utc)
>>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=timezone.utc)
>>> Experiment.objects.create(
... start_datetime=start_2015, start_date=start_2015.date(),
... end_datetime=end_2015, end_date=end_2015.date())
>>> Experiment.objects.annotate(
... year=ExtractYear('start_date'),
... isoyear=ExtractIsoYear('start_date'),
... quarter=ExtractQuarter('start_date'),
... month=ExtractMonth('start_date'),
... week=ExtractWeek('start_date'),
... day=ExtractDay('start_date'),
... weekday=ExtractWeekDay('start_date'),
... isoweekday=ExtractIsoWeekDay('start_date'),
... ).values(
... 'year', 'isoyear', 'quarter', 'month', 'week', 'day', 'weekday',
... 'isoweekday',
... ).get(end_date__year=ExtractYear('start_date'))
{'year': 2015, 'isoyear': 2015, 'quarter': 2, 'month': 6, 'week': 25,
'day': 15, 'weekday': 2, 'isoweekday': 1}
Extractions DateTimeField
¶
En plus de ce qui suit, toutes les extractions pour DateField
Ă©numĂ©rĂ©es ci-dessus peuvent aussi ĂȘtre utilisĂ©es pour DateTimeField
.
-
class
ExtractHour
(expression, tzinfo=None, **extra)¶ -
lookup_name = 'hour'
-
-
class
ExtractMinute
(expression, tzinfo=None, **extra)¶ -
lookup_name = 'minute'
-
-
class
ExtractSecond
(expression, tzinfo=None, **extra)¶ -
lookup_name = 'second'
-
Il sâagit dâĂ©quivalents logiques Ă Extract('champ_datetime', lookup_name)
. Chaque classe est aussi une classe Transform
inscrite pour le champ DateTimeField
comme __(lookup_name)
, par ex. __minute
.
Exemples DateTimeField
:
>>> from datetime import datetime
>>> from django.utils import timezone
>>> from django.db.models.functions import (
... ExtractDay, ExtractHour, ExtractMinute, ExtractMonth,
... ExtractQuarter, ExtractSecond, ExtractWeek, ExtractIsoWeekDay,
... ExtractWeekDay, ExtractIsoYear, ExtractYear,
... )
>>> start_2015 = datetime(2015, 6, 15, 23, 30, 1, tzinfo=timezone.utc)
>>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=timezone.utc)
>>> Experiment.objects.create(
... start_datetime=start_2015, start_date=start_2015.date(),
... end_datetime=end_2015, end_date=end_2015.date())
>>> Experiment.objects.annotate(
... year=ExtractYear('start_datetime'),
... isoyear=ExtractIsoYear('start_datetime'),
... quarter=ExtractQuarter('start_datetime'),
... month=ExtractMonth('start_datetime'),
... week=ExtractWeek('start_datetime'),
... day=ExtractDay('start_datetime'),
... weekday=ExtractWeekDay('start_datetime'),
... isoweekday=ExtractIsoWeekDay('start_datetime'),
... hour=ExtractHour('start_datetime'),
... minute=ExtractMinute('start_datetime'),
... second=ExtractSecond('start_datetime'),
... ).values(
... 'year', 'isoyear', 'month', 'week', 'day',
... 'weekday', 'isoweekday', 'hour', 'minute', 'second',
... ).get(end_datetime__year=ExtractYear('start_datetime'))
{'year': 2015, 'isoyear': 2015, 'quarter': 2, 'month': 6, 'week': 25,
'day': 15, 'weekday': 2, 'isoweekday': 1, 'hour': 23, 'minute': 30,
'second': 1}
Lorsque USE_TZ
vaut True
, les dates/heures sont stockĂ©es en UTC dans la base de donnĂ©es. Si un autre fuseau horaire est actif dans Django, la date/heure est convertie dans ce fuseau avant que la valeur soit extraite. Lâexemple ci-dessous convertit dans le fuseau horaire de Melbourne (UTC +10:00), ce qui modifie les valeurs du jour, du jour de la semaine et de lâheure qui sont renvoyĂ©es :
>>> import pytz
>>> melb = pytz.timezone('Australia/Melbourne') # UTC+10:00
>>> with timezone.override(melb):
... Experiment.objects.annotate(
... day=ExtractDay('start_datetime'),
... weekday=ExtractWeekDay('start_datetime'),
... isoweekday=ExtractIsoWeekDay('start_datetime'),
... hour=ExtractHour('start_datetime'),
... ).values('day', 'weekday', 'isoweekday', 'hour').get(
... end_datetime__year=ExtractYear('start_datetime'),
... )
{'day': 16, 'weekday': 3, 'isoweekday': 2, 'hour': 9}
Le passage explicite du fuseau horaire Ă la fonction Extract
fonctionne de la mĂȘme maniĂšre et prend la prioritĂ© sur le fuseau horaire actif :
>>> import pytz
>>> melb = pytz.timezone('Australia/Melbourne')
>>> Experiment.objects.annotate(
... day=ExtractDay('start_datetime', tzinfo=melb),
... weekday=ExtractWeekDay('start_datetime', tzinfo=melb),
... isoweekday=ExtractIsoWeekDay('start_datetime', tzinfo=melb),
... hour=ExtractHour('start_datetime', tzinfo=melb),
... ).values('day', 'weekday', 'isoweekday', 'hour').get(
... end_datetime__year=ExtractYear('start_datetime'),
... )
{'day': 16, 'weekday': 3, 'isoweekday': 2, 'hour': 9}
Now
¶
-
class
Now
¶
Renvoie la date et lâheure courante du serveur de base de donnĂ©es au moment oĂč la requĂȘte est exĂ©cutĂ©e, typiquement en utilisant le code SQL CURRENT_TIMESTAMP
.
Exemple dâutilisation :
>>> from django.db.models.functions import Now
>>> Article.objects.filter(published__lte=Now())
<QuerySet [<Article: How to Django>]>
Considérations sur PostgreSQL
Avec PostgreSQL, lâinstruction CURRENT_TIMESTAMP
renvoie lâheure du dĂ©but de la transaction actuelle. Par consĂ©quent, pour garantir la compatibilitĂ© entre bases de donnĂ©es, Now()
utilise STATEMENT_TIMESTAMP
Ă la place. Si vous avez besoin de lâhorodatage de la transaction, utilisez django.contrib.postgres.functions.TransactionNow
.
Trunc
¶
-
class
Trunc
(expression, kind, output_field=None, tzinfo=None, is_dst=None, **extra)¶
Tronque une date jusquâĂ un composant significatif.
Lorsque vous ne voulez que savoir si quelque chose sâest produit durant une annĂ©e, une heure ou un jour particulier, mais pas Ă quelle seconde, Trunc
(et ses sous-classes) peut ĂȘtre utile pour filtrer ou agrĂ©ger vos donnĂ©es. Par exemple, vous pouvez utiliser Trunc
pour calculer le nombre de ventes par jour.
Trunc
accepte une seule expression
, représentant un champ DateField
, TimeField
ou DateTimeField
, une variable kind
reprĂ©sentant une partie de date ou dâheure et un champ output_field
qui vaut DateTimeField()
, TimeField()
ou DateField()
. Elle renvoie une date, une heure ou une date/heure en fonction de output_field
, avec les champs jusquâĂ kind
définis à leur valeur minimale. Si output_field
est omis, la valeur par défaut sera le type output_field
de expression
. Il est possible de passer aussi une sous-classe de tzinfo
, habituellement fournie par pytz
, pour tronquer une valeur dans un fuseau horaire spécifique.
Le paramĂštre is_dst
indique si pytz
doit interprĂ©ter les heures non existantes et ambiguĂ«s dans les transitions de changements dâheures saisonniers. Par dĂ©faut (lorsque is_dst=None
), pytz
génÚre une exception pour de telles heures.
Le paramĂštre is_dst
a été ajouté.
Ătant donnĂ©e la date/heure 2015-06-15 14:30:50.000321+00:00
, les valeurs kind
possibles renvoient :
- « year »: 2015-01-01 00:00:00+00:00
- « quarter »: 2015-04-01 00:00:00+00:00
- « month »: 2015-06-01 00:00:00+00:00
- « week »: 2015-06-15 00:00:00+00:00
- « day »: 2015-06-15 00:00:00+00:00
- « hour »: 2015-06-15 14:00:00+00:00
- « minute »: 2015-06-15 14:30:00+00:00
- « second »: 2015-06-15 14:30:50+00:00
Si un fuseau horaire différent comme Australia/Melbourne
est actif dans Django, la date/heure est convertie dans le nouveau fuseau avant que la valeur soit tronquĂ©e. Le dĂ©calage horaire de Melbourne dans la date dâexemple ci-dessus est +10:00. Les valeurs renvoyĂ©es lorsque ce fuseau est actif seront :
- « year »: 2015-01-01 00:00:00+11:00
- « quarter »: 2015-04-01 00:00:00+10:00
- « month »: 2015-06-01 00:00:00+10:00
- « week »: 2015-06-16 00:00:00+10:00
- « day »: 2015-06-16 00:00:00+10:00
- « hour »: 2015-06-16 00:00:00+10:00
- « minute »: 2015-06-16 00:30:00+10:00
- « second »: 2015-06-16 00:30:50+10:00
LâannĂ©e prĂ©sente un dĂ©calage de +11:00 parce que le rĂ©sultat traverse un passage Ă lâheure dâĂ©tĂ©.
Chaque valeur kind
ci-dessus possĂšde une sous-classe de Trunc
correspondante (Ă©numĂ©rĂ©es ci-dessous) qui devrait ĂȘtre utilisĂ©e au lieu de lâĂ©quivalent plus bavard, câest-Ă -dire TruncYear(...)
au lieu de Trunc(..., kind='year')
.
Les sous-classes sont toutes dĂ©finies comme des transformations, mais elles ne sont inscrites pour aucun champ, car les noms de requĂȘte sont dĂ©jĂ rĂ©servĂ©s par les sous-classes de Extract
.
Exemple dâutilisation :
>>> from datetime import datetime
>>> from django.db.models import Count, DateTimeField
>>> from django.db.models.functions import Trunc
>>> Experiment.objects.create(start_datetime=datetime(2015, 6, 15, 14, 30, 50, 321))
>>> Experiment.objects.create(start_datetime=datetime(2015, 6, 15, 14, 40, 2, 123))
>>> Experiment.objects.create(start_datetime=datetime(2015, 12, 25, 10, 5, 27, 999))
>>> experiments_per_day = Experiment.objects.annotate(
... start_day=Trunc('start_datetime', 'day', output_field=DateTimeField())
... ).values('start_day').annotate(experiments=Count('id'))
>>> for exp in experiments_per_day:
... print(exp['start_day'], exp['experiments'])
...
2015-06-15 00:00:00 2
2015-12-25 00:00:00 1
>>> experiments = Experiment.objects.annotate(
... start_day=Trunc('start_datetime', 'day', output_field=DateTimeField())
... ).filter(start_day=datetime(2015, 6, 15))
>>> for exp in experiments:
... print(exp.start_datetime)
...
2015-06-15 14:30:50.000321
2015-06-15 14:40:02.000123
Troncature de DateField
¶
-
class
TruncYear
(expression, output_field=None, tzinfo=None, is_dst=None, **extra)¶ -
kind = 'year'
-
-
class
TruncMonth
(expression, output_field=None, tzinfo=None, is_dst=None, **extra)¶ -
kind = 'month'
-
-
class
TruncWeek
(expression, output_field=None, tzinfo=None, is_dst=None, **extra)¶ Tronque à minuit le lundi de la semaine.
-
kind = 'week'
-
-
class
TruncQuarter
(expression, output_field=None, tzinfo=None, is_dst=None, **extra)¶ -
kind = 'quarter'
-
Ce sont des équivalences logiques à Trunc('champ_date', kind)
. Elles tronquent toutes les parties de la date jusquâĂ kind
, ce qui permet de grouper ou de filtrer des dates avec une plus faible précision. expression
peut avoir une valeur output_field
de DateField
ou de DateTimeField
.
Comme les champs DateField
nâont pas de composant dâheure, seules les sous-classes de Trunc
qui sâappliquent aux parties de date peuvent ĂȘtre utilisĂ©es avec DateField
:
>>> from datetime import datetime
>>> from django.db.models import Count
>>> from django.db.models.functions import TruncMonth, TruncYear
>>> from django.utils import timezone
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
>>> start2 = datetime(2015, 6, 15, 14, 40, 2, 123, tzinfo=timezone.utc)
>>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=timezone.utc)
>>> Experiment.objects.create(start_datetime=start1, start_date=start1.date())
>>> Experiment.objects.create(start_datetime=start2, start_date=start2.date())
>>> Experiment.objects.create(start_datetime=start3, start_date=start3.date())
>>> experiments_per_year = Experiment.objects.annotate(
... year=TruncYear('start_date')).values('year').annotate(
... experiments=Count('id'))
>>> for exp in experiments_per_year:
... print(exp['year'], exp['experiments'])
...
2014-01-01 1
2015-01-01 2
>>> import pytz
>>> melb = pytz.timezone('Australia/Melbourne')
>>> experiments_per_month = Experiment.objects.annotate(
... month=TruncMonth('start_datetime', tzinfo=melb)).values('month').annotate(
... experiments=Count('id'))
>>> for exp in experiments_per_month:
... print(exp['month'], exp['experiments'])
...
2015-06-01 00:00:00+10:00 1
2016-01-01 00:00:00+11:00 1
2014-06-01 00:00:00+10:00 1
Troncature de DateTimeField
¶
-
class
TruncDate
(expression, **extra)¶ -
lookup_name = 'date'
-
output_field = DateField()
-
TruncDate
force le type de expression
Ă une date plutĂŽt que dâutiliser lâinstruction SQL de troncature. Elle est aussi inscrite comme transformation pour DateTimeField
sous la forme __date
.
-
class
TruncTime
(expression, **extra)¶ -
lookup_name = 'time'
-
output_field = TimeField()
-
TruncTime
force le type de expression
Ă une heure plutĂŽt que dâutiliser lâinstruction SQL de troncature. Elle est aussi inscrite comme transformation pour DateTimeField
sous la forme __time
.
-
class
TruncDay
(expression, output_field=None, tzinfo=None, is_dst=None, **extra)¶ -
kind = 'day'
-
-
class
TruncHour
(expression, output_field=None, tzinfo=None, is_dst=None, **extra)¶ -
kind = 'hour'
-
-
class
TruncMinute
(expression, output_field=None, tzinfo=None, is_dst=None, **extra)¶ -
kind = 'minute'
-
-
class
TruncSecond
(expression, output_field=None, tzinfo=None, is_dst=None, **extra)¶ -
kind = 'second'
-
Ce sont des équivalences logiques à Trunc('champ_dateheure', kind)
. Elles tronquent toutes les parties de la date jusquâĂ kind
, ce qui permet de grouper ou de filtrer des dates/heures avec une plus faible précision. expression
doit avoir une valeur output_field
de DateTimeField
.
Exemple dâutilisation :
>>> from datetime import date, datetime
>>> from django.db.models import Count
>>> from django.db.models.functions import (
... TruncDate, TruncDay, TruncHour, TruncMinute, TruncSecond,
... )
>>> from django.utils import timezone
>>> import pytz
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
>>> Experiment.objects.create(start_datetime=start1, start_date=start1.date())
>>> melb = pytz.timezone('Australia/Melbourne')
>>> Experiment.objects.annotate(
... date=TruncDate('start_datetime'),
... day=TruncDay('start_datetime', tzinfo=melb),
... hour=TruncHour('start_datetime', tzinfo=melb),
... minute=TruncMinute('start_datetime'),
... second=TruncSecond('start_datetime'),
... ).values('date', 'day', 'hour', 'minute', 'second').get()
{'date': datetime.date(2014, 6, 15),
'day': datetime.datetime(2014, 6, 16, 0, 0, tzinfo=<DstTzInfo 'Australia/Melbourne' AEST+10:00:00 STD>),
'hour': datetime.datetime(2014, 6, 16, 0, 0, tzinfo=<DstTzInfo 'Australia/Melbourne' AEST+10:00:00 STD>),
'minute': 'minute': datetime.datetime(2014, 6, 15, 14, 30, tzinfo=<UTC>),
'second': datetime.datetime(2014, 6, 15, 14, 30, 50, tzinfo=<UTC>)
}
Troncature de TimeField
¶
-
class
TruncHour
(expression, output_field=None, tzinfo=None, is_dst=None, **extra) -
kind = 'hour'
-
-
class
TruncMinute
(expression, output_field=None, tzinfo=None, is_dst=None, **extra) -
kind = 'minute'
-
-
class
TruncSecond
(expression, output_field=None, tzinfo=None, is_dst=None, **extra) -
kind = 'second'
-
Ce sont des équivalences logiques à Trunc('champ_heure', kind)
. Elles tronquent toutes les parties de lâheure jusquâĂ kind
, ce qui permet de grouper ou de filtrer des heures avec une plus faible précision. expression
peut avoir une valeur output_field
de TimeField
ou de DateTimeField
.
Comme les champs TimeField
nâont pas de composant de date, seules les sous-classes de Trunc
qui sâappliquent aux parties dâheure peuvent ĂȘtre utilisĂ©es avec TimeField
:
>>> from datetime import datetime
>>> from django.db.models import Count, TimeField
>>> from django.db.models.functions import TruncHour
>>> from django.utils import timezone
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
>>> start2 = datetime(2014, 6, 15, 14, 40, 2, 123, tzinfo=timezone.utc)
>>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=timezone.utc)
>>> Experiment.objects.create(start_datetime=start1, start_time=start1.time())
>>> Experiment.objects.create(start_datetime=start2, start_time=start2.time())
>>> Experiment.objects.create(start_datetime=start3, start_time=start3.time())
>>> experiments_per_hour = Experiment.objects.annotate(
... hour=TruncHour('start_datetime', output_field=TimeField()),
... ).values('hour').annotate(experiments=Count('id'))
>>> for exp in experiments_per_hour:
... print(exp['hour'], exp['experiments'])
...
14:00:00 2
17:00:00 1
>>> import pytz
>>> melb = pytz.timezone('Australia/Melbourne')
>>> experiments_per_hour = Experiment.objects.annotate(
... hour=TruncHour('start_datetime', tzinfo=melb),
... ).values('hour').annotate(experiments=Count('id'))
>>> for exp in experiments_per_hour:
... print(exp['hour'], exp['experiments'])
...
2014-06-16 00:00:00+10:00 2
2016-01-01 04:00:00+11:00 1
Fonctions mathématiques¶
Nous allons utiliser le modÚle suivant dans les exemples de fonction mathématique qui suivront :
class Vector(models.Model):
x = models.FloatField()
y = models.FloatField()
Abs
¶
-
class
Abs
(expression, **extra)¶
Renvoie la valeur absolue dâun champ ou dâune expression numĂ©rique.
Exemple dâutilisation :
>>> from django.db.models.functions import Abs
>>> Vector.objects.create(x=-0.5, y=1.1)
>>> vector = Vector.objects.annotate(x_abs=Abs('x'), y_abs=Abs('y')).get()
>>> vector.x_abs, vector.y_abs
(0.5, 1.1)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Abs
>>> FloatField.register_lookup(Abs)
>>> # Get vectors inside the unit cube
>>> vectors = Vector.objects.filter(x__abs__lt=1, y__abs__lt=1)
ACos
¶
-
class
ACos
(expression, **extra)¶
Renvoie lâarccosinus dâun champ ou dâune expression numĂ©rique. La valeur de lâexpression doit se situer dans lâintervalle -1 Ă 1.
Exemple dâutilisation :
>>> from django.db.models.functions import ACos
>>> Vector.objects.create(x=0.5, y=-0.9)
>>> vector = Vector.objects.annotate(x_acos=ACos('x'), y_acos=ACos('y')).get()
>>> vector.x_acos, vector.y_acos
(1.0471975511965979, 2.6905658417935308)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import ACos
>>> FloatField.register_lookup(ACos)
>>> # Get vectors whose arccosine is less than 1
>>> vectors = Vector.objects.filter(x__acos__lt=1, y__acos__lt=1)
ASin
¶
-
class
ASin
(expression, **extra)¶
Renvoie lâarcsinus dâun champ ou dâune expression numĂ©rique. La valeur de lâexpression doit se situer dans lâintervalle -1 Ă 1.
Exemple dâutilisation :
>>> from django.db.models.functions import ASin
>>> Vector.objects.create(x=0, y=1)
>>> vector = Vector.objects.annotate(x_asin=ASin('x'), y_asin=ASin('y')).get()
>>> vector.x_asin, vector.y_asin
(0.0, 1.5707963267948966)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import ASin
>>> FloatField.register_lookup(ASin)
>>> # Get vectors whose arcsine is less than 1
>>> vectors = Vector.objects.filter(x__asin__lt=1, y__asin__lt=1)
ATan
¶
-
class
ATan
(expression, **extra)¶
Renvoie lâarctangente dâun champ ou dâune expression numĂ©rique.
Exemple dâutilisation :
>>> from django.db.models.functions import ATan
>>> Vector.objects.create(x=3.12, y=6.987)
>>> vector = Vector.objects.annotate(x_atan=ATan('x'), y_atan=ATan('y')).get()
>>> vector.x_atan, vector.y_atan
(1.2606282660069106, 1.428638798133829)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import ATan
>>> FloatField.register_lookup(ATan)
>>> # Get vectors whose arctangent is less than 2
>>> vectors = Vector.objects.filter(x__atan__lt=2, y__atan__lt=2)
ATan2
¶
-
class
ATan2
(expression1, expression2, **extra)¶
Renvoie lâarctangente de expression1 / expression2
.
Exemple dâutilisation :
>>> from django.db.models.functions import ATan2
>>> Vector.objects.create(x=2.5, y=1.9)
>>> vector = Vector.objects.annotate(atan2=ATan2('x', 'y')).get()
>>> vector.atan2
0.9209258773829491
Ceil
¶
-
class
Ceil
(expression, **extra)¶
Renvoie le plus petit nombre entier plus grand ou Ă©gal au champ ou Ă lâexpression numĂ©rique.
Exemple dâutilisation :
>>> from django.db.models.functions import Ceil
>>> Vector.objects.create(x=3.12, y=7.0)
>>> vector = Vector.objects.annotate(x_ceil=Ceil('x'), y_ceil=Ceil('y')).get()
>>> vector.x_ceil, vector.y_ceil
(4.0, 7.0)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Ceil
>>> FloatField.register_lookup(Ceil)
>>> # Get vectors whose ceil is less than 10
>>> vectors = Vector.objects.filter(x__ceil__lt=10, y__ceil__lt=10)
Cos
¶
-
class
Cos
(expression, **extra)¶
Renvoie le cosinus dâun champ ou dâune expression numĂ©rique.
Exemple dâutilisation :
>>> from django.db.models.functions import Cos
>>> Vector.objects.create(x=-8.0, y=3.1415926)
>>> vector = Vector.objects.annotate(x_cos=Cos('x'), y_cos=Cos('y')).get()
>>> vector.x_cos, vector.y_cos
(-0.14550003380861354, -0.9999999999999986)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Cos
>>> FloatField.register_lookup(Cos)
>>> # Get vectors whose cosine is less than 0.5
>>> vectors = Vector.objects.filter(x__cos__lt=0.5, y__cos__lt=0.5)
Cot
¶
-
class
Cot
(expression, **extra)¶
Renvoie la cotangente dâun champ ou dâune expression numĂ©rique.
Exemple dâutilisation :
>>> from django.db.models.functions import Cot
>>> Vector.objects.create(x=12.0, y=1.0)
>>> vector = Vector.objects.annotate(x_cot=Cot('x'), y_cot=Cot('y')).get()
>>> vector.x_cot, vector.y_cot
(-1.5726734063976826, 0.642092615934331)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Cot
>>> FloatField.register_lookup(Cot)
>>> # Get vectors whose cotangent is less than 1
>>> vectors = Vector.objects.filter(x__cot__lt=1, y__cot__lt=1)
Degrees
¶
-
class
Degrees
(expression, **extra)¶
Convertit un champ ou une expression numérique de radians en degrés.
Exemple dâutilisation :
>>> from django.db.models.functions import Degrees
>>> Vector.objects.create(x=-1.57, y=3.14)
>>> vector = Vector.objects.annotate(x_d=Degrees('x'), y_d=Degrees('y')).get()
>>> vector.x_d, vector.y_d
(-89.95437383553924, 179.9087476710785)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Degrees
>>> FloatField.register_lookup(Degrees)
>>> # Get vectors whose degrees are less than 360
>>> vectors = Vector.objects.filter(x__degrees__lt=360, y__degrees__lt=360)
Exp
¶
-
class
Exp
(expression, **extra)¶
Renvoie la valeur de e
(la base du logarithme naturel) Ă©levĂ© Ă la puissance du champ ou de lâexpression numĂ©rique.
Exemple dâutilisation :
>>> from django.db.models.functions import Exp
>>> Vector.objects.create(x=5.4, y=-2.0)
>>> vector = Vector.objects.annotate(x_exp=Exp('x'), y_exp=Exp('y')).get()
>>> vector.x_exp, vector.y_exp
(221.40641620418717, 0.1353352832366127)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Exp
>>> FloatField.register_lookup(Exp)
>>> # Get vectors whose exp() is greater than 10
>>> vectors = Vector.objects.filter(x__exp__gt=10, y__exp__gt=10)
Floor
¶
-
class
Floor
(expression, **extra)¶
Renvoie le plus grand nombre entier qui nâest pas plus grand que le champ ou lâexpression numĂ©rique.
Exemple dâutilisation :
>>> from django.db.models.functions import Floor
>>> Vector.objects.create(x=5.4, y=-2.3)
>>> vector = Vector.objects.annotate(x_floor=Floor('x'), y_floor=Floor('y')).get()
>>> vector.x_floor, vector.y_floor
(5.0, -3.0)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Floor
>>> FloatField.register_lookup(Floor)
>>> # Get vectors whose floor() is greater than 10
>>> vectors = Vector.objects.filter(x__floor__gt=10, y__floor__gt=10)
Ln
¶
-
class
Ln
(expression, **extra)¶
Renvoie le logarithme naturel dâun champ ou dâune expression numĂ©rique.
Exemple dâutilisation :
>>> from django.db.models.functions import Ln
>>> Vector.objects.create(x=5.4, y=233.0)
>>> vector = Vector.objects.annotate(x_ln=Ln('x'), y_ln=Ln('y')).get()
>>> vector.x_ln, vector.y_ln
(1.6863989535702288, 5.4510384535657)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Ln
>>> FloatField.register_lookup(Ln)
>>> # Get vectors whose value greater than e
>>> vectors = Vector.objects.filter(x__ln__gt=1, y__ln__gt=1)
Log
¶
-
class
Log
(expression1, expression2, **extra)¶
Accepte deux champs ou expressions numériques et renvoie le logarithme du premier en base du second.
Exemple dâutilisation :
>>> from django.db.models.functions import Log
>>> Vector.objects.create(x=2.0, y=4.0)
>>> vector = Vector.objects.annotate(log=Log('x', 'y')).get()
>>> vector.log
2.0
Mod
¶
-
class
Mod
(expression1, expression2, **extra)¶
Accepte deux champs ou expressions numériques et renvoie le reste du premier divisé par le second (opération modulo).
Exemple dâutilisation :
>>> from django.db.models.functions import Mod
>>> Vector.objects.create(x=5.4, y=2.3)
>>> vector = Vector.objects.annotate(mod=Mod('x', 'y')).get()
>>> vector.mod
0.8
Power
¶
-
class
Power
(expression1, expression2, **extra)¶
Accepte deux champs ou expressions numériques et renvoie la valeur du premier élevé à la puissance du second.
Exemple dâutilisation :
>>> from django.db.models.functions import Power
>>> Vector.objects.create(x=2, y=-2)
>>> vector = Vector.objects.annotate(power=Power('x', 'y')).get()
>>> vector.power
0.25
Radians
¶
-
class
Radians
(expression, **extra)¶
Convertit un champ ou une expression numérique de degrés en radians.
Exemple dâutilisation :
>>> from django.db.models.functions import Radians
>>> Vector.objects.create(x=-90, y=180)
>>> vector = Vector.objects.annotate(x_r=Radians('x'), y_r=Radians('y')).get()
>>> vector.x_r, vector.y_r
(-1.5707963267948966, 3.141592653589793)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Radians
>>> FloatField.register_lookup(Radians)
>>> # Get vectors whose radians are less than 1
>>> vectors = Vector.objects.filter(x__radians__lt=1, y__radians__lt=1)
Round
¶
-
class
Round
(expression, **extra)¶
Arrondit un champ ou une expression numĂ©rique Ă lâentier le plus proche. Lâarrondi vers le haut ou vers le bas des valeurs mĂ©dianes (.5) dĂ©pend de la base de donnĂ©es utilisĂ©e.
Exemple dâutilisation :
>>> from django.db.models.functions import Round
>>> Vector.objects.create(x=5.4, y=-2.3)
>>> vector = Vector.objects.annotate(x_r=Round('x'), y_r=Round('y')).get()
>>> vector.x_r, vector.y_r
(5.0, -2.0)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Round
>>> FloatField.register_lookup(Round)
>>> # Get vectors whose round() is less than 20
>>> vectors = Vector.objects.filter(x__round__lt=20, y__round__lt=20)
Sign
¶
-
class
Sign
(expression, **extra)¶
Renvoie le signe (-1, 0, 1) dâun champ ou dâune expression numĂ©rique.
Exemple dâutilisation :
>>> from django.db.models.functions import Sign
>>> Vector.objects.create(x=5.4, y=-2.3)
>>> vector = Vector.objects.annotate(x_sign=Sign('x'), y_sign=Sign('y')).get()
>>> vector.x_sign, vector.y_sign
(1, -1)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Sign
>>> FloatField.register_lookup(Sign)
>>> # Get vectors whose signs of components are less than 0.
>>> vectors = Vector.objects.filter(x__sign__lt=0, y__sign__lt=0)
Sin
¶
-
class
Sin
(expression, **extra)¶
Renvoie le sinus dâun champ ou dâune expression numĂ©rique.
Exemple dâutilisation :
>>> from django.db.models.functions import Sin
>>> Vector.objects.create(x=5.4, y=-2.3)
>>> vector = Vector.objects.annotate(x_sin=Sin('x'), y_sin=Sin('y')).get()
>>> vector.x_sin, vector.y_sin
(-0.7727644875559871, -0.7457052121767203)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Sin
>>> FloatField.register_lookup(Sin)
>>> # Get vectors whose sin() is less than 0
>>> vectors = Vector.objects.filter(x__sin__lt=0, y__sin__lt=0)
Sqrt
¶
-
class
Sqrt
(expression, **extra)¶
Renvoie la racine carrĂ©e dâun champ ou dâune expression numĂ©rique non nĂ©gative.
Exemple dâutilisation :
>>> from django.db.models.functions import Sqrt
>>> Vector.objects.create(x=4.0, y=12.0)
>>> vector = Vector.objects.annotate(x_sqrt=Sqrt('x'), y_sqrt=Sqrt('y')).get()
>>> vector.x_sqrt, vector.y_sqrt
(2.0, 3.46410)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Sqrt
>>> FloatField.register_lookup(Sqrt)
>>> # Get vectors whose sqrt() is less than 5
>>> vectors = Vector.objects.filter(x__sqrt__lt=5, y__sqrt__lt=5)
Tan
¶
-
class
Tan
(expression, **extra)¶
Renvoie la tangente dâun champ ou dâune expression numĂ©rique.
Exemple dâutilisation :
>>> from django.db.models.functions import Tan
>>> Vector.objects.create(x=0, y=12)
>>> vector = Vector.objects.annotate(x_tan=Tan('x'), y_tan=Tan('y')).get()
>>> vector.x_tan, vector.y_tan
(0.0, -0.6358599286615808)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Tan
>>> FloatField.register_lookup(Tan)
>>> # Get vectors whose tangent is less than 0
>>> vectors = Vector.objects.filter(x__tan__lt=0, y__tan__lt=0)
Fonctions textuelles¶
Chr
¶
-
class
Chr
(expression, **extra)¶
Accepte un champ ou une expression numĂ©rique et renvoie la reprĂ©sentation textuelle de lâexpression sous forme de caractĂšre unique. Il fonctionne comme la fonction chr()
de Python.
Comme Length
, il peut ĂȘtre inscrit comme transformation pour IntegerField
. Le nom de requĂȘte par dĂ©faut est chr
.
Exemple dâutilisation :
>>> from django.db.models.functions import Chr
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.filter(name__startswith=Chr(ord('M'))).get()
>>> print(author.name)
Margaret Smith
Concat
¶
-
class
Concat
(*expressions, **extra)¶
Accepte une liste dâau moins deux champs textes ou expressions et renvoie la concatĂ©nation de ces paramĂštres. Chaque paramĂštre doit ĂȘtre de type texte ou caractĂšre. Si vous voulez concatĂ©ner un champ TextField()
avec un champ CharField()
, prenez alors la prĂ©caution dâindiquer Ă Django que le rĂ©sultat output_field
sera un champ TextField()
. Câest aussi nĂ©cessaire lors de la concatĂ©nation avec une valeur Value
comme dans lâexemple ci-dessous.
Le rĂ©sultat de cette fonction nâest jamais nul. Pour les moteurs oĂč un paramĂštre nul aboutit Ă ce que toute lâexpression devienne nulle, Django sâassure que chaque partie nulle est prĂ©alablement convertie en chaĂźne vide.
Exemple dâutilisation :
>>> # 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)
Left
¶
-
class
Left
(expression, length, **extra)¶
Renvoie les n (length
) premiers caractĂšres du champ texte ou de lâexpression donnĂ©e.
Exemple dâutilisation :
>>> from django.db.models.functions import Left
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(first_initial=Left('name', 1)).get()
>>> print(author.first_initial)
M
Length
¶
-
class
Length
(expression, **extra)¶
Accepte un champ texte ou une expression unique et renvoie le nombre de caractĂšres de la valeur. Si lâexpression est nulle, la longueur renvoyĂ©e sera Ă©galement nulle.
Exemple dâutilisation :
>>> # 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)
Cette expression peut aussi ĂȘtre inscrite comme transformation. Par exemple :
>>> from django.db.models import CharField
>>> from django.db.models.functions import Length
>>> CharField.register_lookup(Length)
>>> # Get authors whose name is longer than 7 characters
>>> authors = Author.objects.filter(name__length__gt=7)
Lower
¶
-
class
Lower
(expression, **extra)¶
Accepte un champ texte ou une expression unique et renvoie sa représentation en minuscules.
Cette expression peut aussi ĂȘtre inscrite comme transformation comme expliquĂ© pour Length
.
Exemple dâutilisation :
>>> 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
LPad
¶
-
class
LPad
(expression, length, fill_text=Value(' '), **extra)¶
Renvoie la valeur du champ texte ou de lâexpression donnĂ©e remplie Ă sa gauche par fill_text
afin que la longueur de la valeur résultante possÚde length
caractÚres. La valeur par défaut de fill_text
est un espace.
Exemple dâutilisation :
>>> from django.db.models import Value
>>> from django.db.models.functions import LPad
>>> Author.objects.create(name='John', alias='j')
>>> Author.objects.update(name=LPad('name', 8, Value('abc')))
1
>>> print(Author.objects.get(alias='j').name)
abcaJohn
LTrim
¶
-
class
LTrim
(expression, **extra)¶
Semblable Ă Trim
, mais nâenlĂšve que les espaces de dĂ©but de chaĂźne.
MD5
¶
-
class
MD5
(expression, **extra)¶
Accepte un champ texte ou une expression unique et renvoie lâempreinte MD5 de la chaĂźne.
Cette expression peut aussi ĂȘtre inscrite comme transformation comme expliquĂ© pour Length
.
Exemple dâutilisation :
>>> from django.db.models.functions import MD5
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(name_md5=MD5('name')).get()
>>> print(author.name_md5)
749fb689816b2db85f5b169c2055b247
Ord
¶
-
class
Ord
(expression, **extra)¶
Accepte un seul champ texte ou une expression et renvoie la valeur du point de code Unicode du premier caractĂšre de cette expression. Il fonctionne comme la fonction ord()
de Python, mais aucune exception nâest gĂ©nĂ©rĂ©e si lâexpression comporte plus dâun caractĂšre.
Cette expression peut aussi ĂȘtre inscrite comme transformation comme expliquĂ© pour Length
. Le nom de requĂȘte par dĂ©faut est ord
.
Exemple dâutilisation :
>>> from django.db.models.functions import Ord
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(name_code_point=Ord('name')).get()
>>> print(author.name_code_point)
77
Repeat
¶
-
class
Repeat
(expression, number, **extra)¶
Renvoie la valeur du champ texte ou de lâexpression indiquĂ©e rĂ©pĂ©tĂ©e number
fois.
Exemple dâutilisation :
>>> from django.db.models.functions import Repeat
>>> Author.objects.create(name='John', alias='j')
>>> Author.objects.update(name=Repeat('name', 3))
1
>>> print(Author.objects.get(alias='j').name)
JohnJohnJohn
Replace
¶
-
class
Replace
(expression, text, replacement=Value(''), **extra)¶
Remplace toutes les occurrences de text
dans expression
par replacement
. Le texte de remplacement par défaut est la chaßne vide. Les paramÚtres de la fonction sont sensibles à la casse.
Exemple dâutilisation :
>>> from django.db.models import Value
>>> from django.db.models.functions import Replace
>>> Author.objects.create(name='Margaret Johnson')
>>> Author.objects.create(name='Margaret Smith')
>>> Author.objects.update(name=Replace('name', Value('Margaret'), Value('Margareth')))
2
>>> Author.objects.values('name')
<QuerySet [{'name': 'Margareth Johnson'}, {'name': 'Margareth Smith'}]>
Reverse
¶
-
class
Reverse
(expression, **extra)¶
Accepte un champ texte ou une expression unique et renvoie les caractĂšres de cette expression en ordre inverse.
Cette expression peut aussi ĂȘtre inscrite comme transformation comme expliquĂ© pour Length
. Le nom de requĂȘte par dĂ©faut est reverse
.
Exemple dâutilisation :
>>> from django.db.models.functions import Reverse
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(backward=Reverse('name')).get()
>>> print(author.backward)
htimS teragraM
Right
¶
-
class
Right
(expression, length, **extra)¶
Renvoie les n (length
) derniers caractĂšres du champ texte ou de lâexpression donnĂ©e.
Exemple dâutilisation :
>>> from django.db.models.functions import Right
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(last_letter=Right('name', 1)).get()
>>> print(author.last_letter)
h
RPad
¶
-
class
RPad
(expression, length, fill_text=Value(' '), **extra)¶
Semblable Ă LPad
, mais applique le remplissage en fin de chaĂźne.
RTrim
¶
-
class
RTrim
(expression, **extra)¶
Semblable Ă Trim
, mais nâenlĂšve que les espaces de fin de chaĂźne.
SHA1
, SHA224
, SHA256
, SHA384
et SHA512
¶
-
class
SHA1
(expression, **extra)¶
-
class
SHA224
(expression, **extra)¶
-
class
SHA256
(expression, **extra)¶
-
class
SHA384
(expression, **extra)¶
-
class
SHA512
(expression, **extra)¶
Accepte un champ texte ou une expression unique et renvoie lâempreinte correspondante de la chaĂźne.
Elles peuvent aussi ĂȘtre inscrites comme transformations comme expliquĂ© pour Length
.
Exemple dâutilisation :
>>> from django.db.models.functions import SHA1
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(name_sha1=SHA1('name')).get()
>>> print(author.name_sha1)
b87efd8a6c991c390be5a68e8a7945a7851c7e5c
PostgreSQL
Lâextension pgcrypto doit ĂȘtre installĂ©e. Vous pouvez utiliser lâopĂ©ration de migration CryptoExtension
pour lâinstaller.
Oracle
Oracle ne prend pas en charge la fonction SHA224
.
StrIndex
¶
-
class
StrIndex
(string, substring, **extra)¶
Renvoie un nombre entier positif correspondant à la position indicée (commençant à 1) de la premiÚre occurrence de substring
dans string
, ou 0 si substring
est introuvable.
Exemple dâutilisation :
>>> 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')
>>> Author.objects.filter(name='Margaret Jackson').annotate(
... smith_index=StrIndex('name', V('Smith'))
... ).get().smith_index
0
>>> authors = Author.objects.annotate(
... smith_index=StrIndex('name', V('Smith'))
... ).filter(smith_index__gt=0)
<QuerySet [<Author: Margaret Smith>, <Author: Smith, Margaret>]>
Avertissement
Avec MySQL, la collation dâune table de base de donnĂ©es dĂ©termine si les comparaisons de chaĂźnes (telles que dans expression
et substring
de cette fonction) sont sensibles à la casse. Par défaut, les comparaisons ne sont pas sensibles à la casse.
Substr
¶
-
class
Substr
(expression, pos, length=None, **extra)¶
Renvoie une sous-chaĂźne de longueur length
extraite du champ ou de lâexpression Ă partir de la position pos
. Lâindice de position commence Ă 1, il doit donc ĂȘtre plus grand que 0. Si length
vaut None
, tout le reste de la chaßne est renvoyé comme résultat.
Exemple dâutilisation :
>>> # Set the alias to the first 5 characters of the name as lowercase
>>> from django.db.models.functions import Lower, Substr
>>> 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
Trim
¶
-
class
Trim
(expression, **extra)¶
Renvoie la valeur du champ texte ou de lâexpression indiquĂ©e sans les espaces de dĂ©but et de fin de chaĂźne.
Exemple dâutilisation :
>>> from django.db.models.functions import Trim
>>> Author.objects.create(name=' John ', alias='j')
>>> Author.objects.update(name=Trim('name'))
1
>>> print(Author.objects.get(alias='j').name)
John
Upper
¶
-
class
Upper
(expression, **extra)¶
Accepte un champ texte ou une expression unique et renvoie sa représentation en majuscules.
Cette expression peut aussi ĂȘtre inscrite comme transformation comme expliquĂ© pour Length
.
Exemple dâutilisation :
>>> 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
Fonctions de fenĂȘtrage¶
Il existe un certain nombre de fonctions Ă utiliser dans une expression Window
pour calculer la position des éléments ou le Ntile
de certaines lignes.
CumeDist
¶
-
class
CumeDist
(*expressions, **extra)¶
Calcule la distribution cumulative dâune valeur Ă lâintĂ©rieur dâune fenĂȘtre ou dâune partition. La distribution cumulative est dĂ©finie comme le nombre de lignes prĂ©cĂ©dant ou apparentĂ©es Ă la ligne actuelle divisĂ© par le nombre total de lignes dans lâintervalle.
FirstValue
¶
-
class
FirstValue
(expression, **extra)¶
Renvoie la valeur Ă©valuĂ©e Ă la ligne se situant en premier dans lâintervalle de fenĂȘtre, ou None
si une telle valeur nâexiste pas.
Lag
¶
-
class
Lag
(expression, offset=1, default=None, **extra)¶
Calcule le décalage de valeur selon offset
, et si aucune ligne nâexiste Ă cet endroit, renvoie default
.
default
doit avoir le mĂȘme type que expression
; cependant, cette validation se fait dans la base de données et pas dans le code Python.
MariaDB et default
MariaDB ne prend pas en charge le paramĂštre default
.
LastValue
¶
-
class
LastValue
(expression, **extra)¶
Comparable Ă FirstValue
, renvoie la derniĂšre valeur dans une clause dâintervalle donnĂ©e.
Lead
¶
-
class
Lead
(expression, offset=1, default=None, **extra)¶
Calcule la valeur de tĂȘte dans un intervalle donnĂ©. offset
et default
sont tous deux évalués en fonction de la ligne actuelle.
default
doit avoir le mĂȘme type que expression
; cependant, cette validation se fait dans la base de données et pas dans le code Python.
MariaDB et default
MariaDB ne prend pas en charge le paramĂštre default
.
NthValue
¶
-
class
NthValue
(expression, nth=1, **extra)¶
Calcule la ligne relative au décalage nth
(la valeur doit ĂȘtre positive) Ă lâintĂ©rieur de la fenĂȘtre. Renvoie None
si aucune ligne ne correspond.
Certaines bases de données gÚrent différemment une niÚme valeur inexistante. Par exemple, Oracle renvoie une chaßne vide au lieu de None
pour les expressions basĂ©es sur des caractĂšres. Django nâapplique aucune conversion dans ces cas.
Ntile
¶
-
class
Ntile
(num_buckets=1, **extra)¶
Calcule une partition pour chacune des lignes dans la clause dâintervalle, distribuant les nombres aussi Ă©galement que possible entre 1 et num_buckets
. Si les lignes ne sont pas divisibles de maniÚre égale par le nombre de « buckets », un ou plusieurs de ceux-ci seront représentés plus fréquemment.
PercentRank
¶
-
class
PercentRank
(*expressions, **extra)¶
Calcule le rang de centile des lignes dans la clause dâintervalle. Ce calcul est Ă©quivalent Ă lâĂ©valuation de
(rank - 1) / (total rows - 1)
Le tableau suivant explique le calcul du rang de centile dâune ligne :
N° de ligne | Valeur | Rang | Calcul | Rang en pourcentage |
---|---|---|---|---|
1 | 15 | 1 | (1-1)/(7-1) | 0.0000 |
2 | 20 | 2 | (2-1)/(7-1) | 0.1666 |
3 | 20 | 2 | (2-1)/(7-1) | 0.1666 |
4 | 20 | 2 | (2-1)/(7-1) | 0.1666 |
5 | 30 | 5 | (5-1)/(7-1) | 0.6666 |
6 | 30 | 5 | (5-1)/(7-1) | 0.6666 |
7 | 40 | 7 | (7-1)/(7-1) | 1.0000 |
Rank
¶
-
class
Rank
(*expressions, **extra)¶
Comparable Ă RowNumber
, cette fonction calcule le rang des lignes de la fenĂȘtre. Le rang calculĂ© comporte des trous. Utilisez DenseRank
pour calculer le rang sans trous.
RowNumber
¶
-
class
RowNumber
(*expressions, **extra)¶
Calcule le numĂ©ro de ligne selon le tri de la clause dâintervalle ou selon le tri de toute la requĂȘte sâil nây a pas partition dans lâintervalle de fenĂȘtre.