Nathanna CoinníollachLink to this heading

Ligeann abairtí coinníollach duit úsáid:eochairfhocal: if `... :keyword: `elif... :keyword: loighic else laistigh de scagairí, anótaí, comhiomlánaithe agus nuashonruithe. Déanann abairt choinníollach measúnú ar shraith coinníollacha do gach sraith de thábla agus tugann sé an léiriú torthaí meaitseála ar ais. <expressions>Is féidir nathanna coinníollach a chomhcheangal agus a neadadh cosúil le chéile freisin: doc: `abairtí `.

Na ranganna léirithe coinníollachLink to this heading

Beidh muid ag úsáid an tsamhail seo a leanas sna samplaí ina dhiaidh sin:

Code
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. 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í:

Python console
>>> 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:

Python console
>>>
>>> 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:

Python console
>>> 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:

Python console
>>> 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:

Python console
>>> 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:

Python console
>>> # 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:

SQL
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:

SQL
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:

Python console
>>> 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:

SQL
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
)