Nathanna CoinníollachLink to this heading
Conditional expressions let you use if ... elif ...
else logic within filters, annotations, aggregations, and updates. A
conditional expression evaluates a series of conditions for each row of a table
and returns the matching result expression. Conditional expressions can also be
combined and nested like other expressions.
Na ranganna léirithe coinníollachLink to this heading
Beidh muid ag úsáid an tsamhail seo a leanas sna samplaí ina dhiaidh sin:
from django.db import models
class Client(models.Model):
REGULAR = "R"
GOLD = "G"
PLATINUM = "P"
ACCOUNT_TYPE_CHOICES = {
REGULAR: "Regular",
GOLD: "Gold",
PLATINUM: "Platinum",
}
name = models.CharField(max_length=50)
registered_on = models.DateField()
account_type = models.CharField(
max_length=1,
choices=ACCOUNT_TYPE_CHOICES,
default=REGULAR,
)
Cén uaireLink to this heading
- class When(condition=None, then=None, **lookups)Link to this definition
Úsáidtear réad Nuair () ``chun coinníoll agus a thoradh a chumhdú le húsáid sa léiriú coinníollach. Tá réad ``When () ``a úsáid cosúil leis an modh: meth: `~django.db.models.query.queryset.filter` a úsáid. Is féidir an coinníoll a shonrú ag baint úsáidea:ref: `field lookups <field-lookups>`, :class: `~django.db.models.q` rudaí, nó: class: `~django.db.Models.Expression` rudaí a bhfuil ``output_field atá a:class: ~django.db.models.booleanfield. Cuirtear an toradh ar fáil ag baint úsáide as an eochairfhocal ``then ``.
Roinnt samplaí:
>>> from django.db.models import F, Q, When
>>> # String arguments refer to fields; the following two examples are equivalent:
>>> When(account_type=Client.GOLD, then="name")
>>> When(account_type=Client.GOLD, then=F("name"))
>>> # You can use field lookups in the condition
>>> from datetime import date
>>> When(
... registered_on__gt=date(2014, 1, 1),
... registered_on__lt=date(2015, 1, 1),
... then="account_type",
... )
>>> # Complex conditions can be created using Q objects
>>> When(Q(name__startswith="John") | Q(name__startswith="Paul"), then="name")
>>> # Condition can be created using boolean expressions.
>>> from django.db.models import Exists, OuterRef
>>> non_unique_account_type = (
... Client.objects.filter(
... account_type=OuterRef("account_type"),
... )
... .exclude(pk=OuterRef("pk"))
... .values("pk")
... )
>>> When(Exists(non_unique_account_type), then=Value("non unique"))
>>> # Condition can be created using lookup expressions.
>>> from django.db.models.lookups import GreaterThan, LessThan
>>> When(
... GreaterThan(F("registered_on"), date(2014, 1, 1))
... & LessThan(F("registered_on"), date(2015, 1, 1)),
... then="account_type",
... )
Coinnigh i gcuimhne gur féidir le gach ceann de na luachanna seo a bheith ina léiriú.
``Cás ``Link to this heading
- class Case(*cases, **extra)Link to this definition
Tá abairt Cás () ``cosúil leis an:keyword: `if `... :keyword: `elif`... :keyword: ráiteas `else` i ``Python. Déantar gach coinníoll sna rudaí Nuair () ``curtha ar fáil a mheas in ord, go dtí go ndéanfaidh duine measúnú ar luach fírinneach. Cuirtear an abairt ``torth ón réad meaitseála ``When () ``ar ais.
Sampla:
>>>
>>> from datetime import date, timedelta
>>> from django.db.models import Case, Value, When
>>> Client.objects.create(
... name="Jane Doe",
... account_type=Client.REGULAR,
... registered_on=date.today() - timedelta(days=36),
... )
>>> Client.objects.create(
... name="James Smith",
... account_type=Client.GOLD,
... registered_on=date.today() - timedelta(days=5),
... )
>>> Client.objects.create(
... name="Jack Black",
... account_type=Client.PLATINUM,
... registered_on=date.today() - timedelta(days=10 * 365),
... )
>>> # Get the discount for each Client based on the account type
>>> Client.objects.annotate(
... discount=Case(
... When(account_type=Client.GOLD, then=Value("5%")),
... When(account_type=Client.PLATINUM, then=Value("10%")),
... default=Value("0%"),
... ),
... ).values_list("name", "discount")
<QuerySet [('Jane Doe', '0%'), ('James Smith', '5%'), ('Jack Black', '10%')]>
Glacann Cás () ``le haon líon de chrudaí ``Nuair () mar argóintí aonair. Cuirtear roghanna eile ar fáil trí argóintí eochairfhocal Mura ndéanann aon cheann de na coinníollacha measúnú ar TRUE, ansin cuirtear an abairt a thugtar leis an argóint eochairfhocal réamhshocraithe ar ais. Mura gcuirtear argóint réamhshocraithe ar fáil, úsáidtear None.
Dá mbeimis ag iarraidh ár bhfiosrú roimhe seo a athrú chun an lascaine a fháil bunaithe ar cé chomh fada agus a bhí an `Cliant ``linn, d'fhéadfaimis é sin a dhéanamh ag baint úsáide as cuardaigh:
>>> a_month_ago = date.today() - timedelta(days=30)
>>> a_year_ago = date.today() - timedelta(days=365)
>>> # Get the discount for each Client based on the registration date
>>> Client.objects.annotate(
... discount=Case(
... When(registered_on__lte=a_year_ago, then=Value("10%")),
... When(registered_on__lte=a_month_ago, then=Value("5%")),
... default=Value("0%"),
... )
... ).values_list("name", "discount")
<QuerySet [('Jane Doe', '5%'), ('James Smith', '0%'), ('Jack Black', '10%')]>
Oibríonn Cás () ``freisin i gclásal ``scagaire (). Mar shampla, chun cliaint óir a chláraigh níos mó ná mí ó shin agus cliaint platanam a chláraigh níos mó ná bliain ó shin a fháil:
>>> a_month_ago = date.today() - timedelta(days=30)
>>> a_year_ago = date.today() - timedelta(days=365)
>>> Client.objects.filter(
... registered_on__lte=Case(
... When(account_type=Client.GOLD, then=a_month_ago),
... When(account_type=Client.PLATINUM, then=a_year_ago),
... ),
... ).values_list("name", "account_type")
<QuerySet [('Jack Black', 'P')]>
Fiosruithe chun cinnLink to this heading
Is féidir nathanna coinníollach a úsáid in anótaí, comhiomlánaithe, scagairí, cuardaigh agus nuashonruithe. Is féidir iad a chomhcheangal agus a neadú le nathanna eile freisin. Ligeann sé seo duit ceisteanna coinníollacha cumhachtacha a dhéanamh.
Nuashonrú coinníollLink to this heading
Abair go dteastaíonn uainn an account_type` a athrú chun dátaí cláraithe a mheaitseáil dátaí cláraithe. Is féidir linn é seo a dhéanamh ag baint úsáide as abairt choinníollach agus an modh:meth: ~django.db.models.query.queryset.update:
>>> a_month_ago = date.today() - timedelta(days=30)
>>> a_year_ago = date.today() - timedelta(days=365)
>>> # Update the account_type for each Client from the registration date
>>> Client.objects.update(
... account_type=Case(
... When(registered_on__lte=a_year_ago, then=Value(Client.PLATINUM)),
... When(registered_on__lte=a_month_ago, then=Value(Client.GOLD)),
... default=Value(Client.REGULAR),
... ),
... )
>>> Client.objects.values_list("name", "account_type")
<QuerySet [('Jane Doe', 'G'), ('James Smith', 'R'), ('Jack Black', 'P')]>
Comhiomlánú coinníollachLink to this heading
Cad a tharlaíonn más mian linn a fháil amach cé mhéad cliant atá ann do gach account_type? <aggregation-functions>Is féidir linn an argóint scagair de:ref: feidhmeanna comhiomlána` a úsáid chun é seo a bhaint amach:
>>> # Create some more Clients first so we can have something to count
>>> Client.objects.create(
... name="Jean Grey", account_type=Client.REGULAR, registered_on=date.today()
... )
>>> Client.objects.create(
... name="James Bond", account_type=Client.PLATINUM, registered_on=date.today()
... )
>>> Client.objects.create(
... name="Jane Porter", account_type=Client.PLATINUM, registered_on=date.today()
... )
>>> # Get counts for each value of account_type
>>> from django.db.models import Count
>>> Client.objects.aggregate(
... regular=Count("pk", filter=Q(account_type=Client.REGULAR)),
... gold=Count("pk", filter=Q(account_type=Client.GOLD)),
... platinum=Count("pk", filter=Q(account_type=Client.PLATINUM)),
... )
{'regular': 2, 'gold': 1, 'platinum': 3}
Táirgeann an comhiomlán seo ceist leis an gcomhréir SQL 2003 FILTER WHERE ar bhunachair sonraí a thacaíonn leis:
SELECT count('id') FILTER (WHERE account_type=1) as regular,
count('id') FILTER (WHERE account_type=2) as gold,
count('id') FILTER (WHERE account_type=3) as platinum
FROM clients;
Ar bhunachair sonraí eile, déantar aithris a dhéanamh air seo ag baint úsáide as ráiteas CÁISE:
SELECT count(CASE WHEN account_type=1 THEN id ELSE null) as regular,
count(CASE WHEN account_type=2 THEN id ELSE null) as gold,
count(CASE WHEN account_type=3 THEN id ELSE null) as platinum
FROM clients;
Tá an dá ráiteas SQL coibhéiseach go feidhmiúil ach b'fhéidir go bhfeidhmeoidh an FILTER` níos follasaí feidhmiú níos fearr.
Scagaire coinníollachLink to this heading
Nuair a thugann abairt choinníollach luach boolean ar ais, is féidir é a úsáid go díreach i scagairí. Ciallaíonn sé seo nach gcuirfear é leis na colúin SELECT, ach is féidir leat é a úsáid fós chun torthaí a scagadh:
>>> non_unique_account_type = (
... Client.objects.filter(
... account_type=OuterRef("account_type"),
... )
... .exclude(pk=OuterRef("pk"))
... .values("pk")
... )
>>> Client.objects.filter(~Exists(non_unique_account_type))
I dtéarmaí SQL, déanann sé meastóireacht ar:
SELECT ...
FROM client c0
WHERE NOT EXISTS (
SELECT c1.id
FROM client c1
WHERE c1.account_type = c0.account_type AND NOT c1.id = c0.id
)