Conas réimsí samhail saincheaptha a chruthúLink to this heading

RéamhráLink to this heading

Míníonn an doiciméad:doc: tagairt samhail </topics/db/models> conas ranganna réimse caighdeánacha Django a úsáid --:class: ~django.db.models.charfield, :class: ~django.db.models.datefield, srl Chun go leor críocha, is iad na ranganna sin gach rud a theastaíonn uait. Uaireanta, áfach, ní chomhlíonfaidh an leagan Django do riachtanais bheachta, nó beidh tú ag iarraidh réimse a úsáid atá go hiomlán difriúil ó na cinn a sheoltar le Django.

Ní chlúdaíonn cineálacha réimse ionsuite Django gach cineál colún bunachar sonraí féideartha - ach na cineálacha coitianta, mar shampla VARCHAR agus INTEGER. Le haghaidh cineálacha colún níos doiléire, mar shampla polagóin gheografacha nó fiú cineálacha cruthaithe ag úsáideoir mar cineálacha saincheaptha PostgreSQL `_, is féidir leat do fho-aicmí ``Field` Django féin a shainiú.

De rogha air sin, b'fhéidir go bhfuil réad casta Python agat is féidir a shraitheadh ar bhealach éigin chun oiriúnú i gcineál colún bunachar sonraí caighdeán Is cás eile é seo ina gcabhróidh fo-aicme ``Field` leat do réad a úsáid le do mhúnlaí.

Ár réad samplachLink to this heading

Éilíonn beagán aird ar mhionsonraí réimsí saincheaptha a chruthú. Chun rudaí a dhéanamh níos éasca a leanúint, úsáidfimid sampla comhsheasmhach ar fud an doiciméad seo: timfhilleadh réad Python a léiríonn déileáil na gcártaí i lámh Bridge. Ná bíodh imní ort, ní gá go mbeadh a fhios agat conas Droichead a imirt chun an sampla seo a leanúint. Ní gá go mbeadh a fhios agat ach go ndéileálfar 52 cárta amach go cothrom le ceithre imreoir, ar a dtugtar go traidisiúnta thuaidh, thoir, theas agus iarth orthu. Breathnaíonn ár rang rud éigin mar seo:

Code
class Hand:
    """A hand of cards (bridge style)"""

    def __init__(self, north, east, south, west):
        # Input parameters are lists of cards ('Ah', '9s', etc.)
        self.north = north
        self.east = east
        self.south = south
        self.west = west

    # ... (other possibly useful methods omitted) ...

Is gnáth-rang Python é seo, gan aon rud Django-sonrach faoi. Ba mhaith linn a bheith in ann rudaí mar seo a dhéanamh inár samhlacha (glacaimid leis gur sampla de Hand é an tréith láimh ar an tsamhail):

Code
example = MyModel.objects.get(pk=1)
print(example.hand.north)

new_hand = Hand(north, east, south, west)
example.hand = new_hand
example.save()

Sannaímid agus aisghabháil uaidh an tréith hand inár samhail díreach cosúil le haon rang Python eile. Is é an cleas ná insint le Django conas rud den sórt sin a shábháil agus a luchtú a láimhseáil.

D'fhonn an rang Hand a úsáid inár samhlacha, ní gá dúinn** an rang seo a athrú ar chor ar bith. Tá sé seo oiriúnach, mar ciallaíonn sé gur féidir leat tacaíocht mhúnla a scríobh go héasca do ranganna atá ann cheana nach féidir leat an cód foinse a athrú.

Teoiric chúlraLink to this heading

Stóráil bunachar sonraíLink to this heading

Tosaímid le réimsí samhail. Má bhriseann tú síos é, soláthraíonn réimse samhail bealach chun gnáthrud Python a thógáil - string, boolean, datetime`, nó rud éigin níos casta cosúil le Hand` - agus é a thiontú go formáid atá úsáideach agus tú ag déileáil leis an mbunachar sonraí. (Tá formáid den sórt sin úsáideach freisin le haghaidh sraitheadh, ach mar a fheicfimid níos déanaí, tá sé sin níos éasca nuair a bheidh an taobh bunachar sonraí faoi smacht agat).

Caithfear réimsí i samhail a thiontú ar bhealach éigin chun oiriúnú i gcineál colún bunachar sonraí atá ann Soláthraíonn bunachair sonraí éagsúla tacair éagsúla de chineálacha bailí colún, ach tá an riail fós mar an gcéanna: is iad sin na cineálacha amháin a chaithfidh tú oibriú leo. Caithfidh aon rud is mian leat a stóráil sa bhunachar sonraí a bheith oiriúnach i gceann de na cineálacha sin.

De ghnáth, tá réimse Django á scríobh agat chun cineál colún bunachar sonraí áirithe a mheaitseáil, nó beidh bealach ag teastáil uait chun do chuid sonraí a thiontú go, abair, sreang.

Maidir lenár sampla Hand, d'fhéadfaimis sonraí na gcárta a thiontú go sreang de 104 carachtar trí na cártaí go léir a chomhcheangal le chéile in ord réamhshocraithe - abair, na cártaí*thuaidh* go léir ar dtús, ansin na cártaí*thoir*, theas agus iarth. Mar sin is féidir rudaí Hand a shábháil i gcolúin téacs nó carachtair sa bhunachar sonraí.

Cad a dhéanann rang allamuigh?Link to this heading

Is fo-aicmí: Django.db.Models.Field iad réimsí uile Django (agus nuair a deirimid *réimsí * sa doiciméad seo, ciallaíonn muid i gcónaí réimsí samhlacha agus ní: doc: réimsí foirme). </ref/forms/fields> Tá an chuid is mó den fhaisnéis a thaifeadann Django faoi réimse coitianta do gach réimse - ainm, téacs cabhrach, uathúlacht agus mar sin de. Láimhseálann Field` an fhaisnéis sin go léir a stóráil. Téimid isteach sna sonraí beachta faoi na rudaí is féidir le ``Field` a dhéanamh níos déanaí; go dtí seo, is leor a go dtagann gach rud as ``Field agus ansin saincheapann sé príomhphíosaí d'iompar an ranga.

Tá sé tábhachtach a thuiscint nach é rang réimse Django an rud a stóráiltear i do thréithe samhail. Tá gnáth-rudaí Python sna tréithe samhail. Stóráiltear na ranganna allamuigh a shainmhíníonn tú i samhail i ndáiríre sa rang ``Meta` nuair a chruthaítear an rang samhail (níl na sonraí beachta faoi conas a dhéantar é seo gan tábhacht anseo). Tá sé seo toisc nach bhfuil na ranganna allamuigh riachtanach nuair nach bhfuil tú ach tréithe a chruthú agus a mhodhnú. Ina áit sin, soláthraíonn siad an t-innealra chun tiontú idir luach na tréithe agus an méid a stóráiltear sa bhunachar sonraí nó a sheoltar chuig:doc: </topics/serialization> serializer.

Coinnigh é seo i gcuimhne agus tú ag cruthú do réimsí saincheaptha féin. Soláthraíonn fo-aicme “Field” Django a scríobhann tú an t-innealra chun tiontú idir do chásanna Python agus na luachanna bunachar sonraí/serializer ar bhealaí éagsúla (tá difríochtaí idir luach a stóráil agus luach a úsáid le haghaidh cuardaigh, mar shampla). Má tá sé seo rud beag deacair, ná bíodh imní ort - beidh sé níos soiléire sna samplaí thíos. Cuimhnigh go ndéanfaidh tú dhá rang a chruthú go minic nuair a theastaíonn réimse saincheaptha uait:

  • Is é an chéad rang an réad Python a ionramhfaidh d'úsáideoirí. Sannóidh siad é don tréith samhail, léifidh siad uaidh chun críocha a thaispeáint, rudaí mar sin. Seo an rang Hand inár sampla.

  • Is é an dara rang an fo-aicme ``Field`. Is é seo an rang a bhfuil a fhios aige conas do chéad rang a thiontú anall agus anall idir a fhoirm stórála buan agus an fhoirm Python.

Fo-aicme réimse a scríobhLink to this heading

Agus do fho-rang: Class: ~Django.db.Models.Field á phleanáil agat, smaoineamh ar dtús cén aicme: ~django.db.models.field atá ar do réimse nua is cosúil leis. An féidir leat réimse Django atá ann cheana a fho-aicmiú agus roinnt oibre a shábháil duit féin? Mura bhfuil, ba chóir duit an rang:class: ~Django.db.Models.Field a fho-aicmiú, as a bhfuil gach rud síos.

Is ábhar do réimse nua a thionscnamh ná aon argóintí atá sonrach do chás a scaradh ó na hargóintí coitianta agus an dara ceann a chur chuig an modh ``__init__ () ``de:class: ~django.db.Models.field (nó do rang tuismitheora).

Inár sampla, glaoimid ar ár réimse ``Handfield`. <Something>(Is smaoineamh maith é glaoch ar do: class: ~django.db.models.field fo-aicme ``Field`, mar sin is féidir é a aithint go héasca mar a:class: ~Django.db.Models.Field fo-aicme.) Ní iompraíonn sé cosúil le haon réimse atá ann cheana, mar sin déanfaimid fo-aicme go díreach ó:class: ~django.db.models.field:

Code
from django.db import models


class HandField(models.Field):
    description = "A hand of cards (bridge style)"

    def __init__(self, *args, **kwargs):
        kwargs["max_length"] = 104
        super().__init__(*args, **kwargs)

Glacann ár “Handfield” leis an gcuid is mó de na roghanna caighdeánacha réimse (féach an liosta thíos), ach cinntímid go bhfuil fad seasta aige, ós rud é nach gá dó ach 52 luach cárta móide a gcuid culaith a shealbhú; 104 carachtar san iomlán.

An ``Réimse. Glacann modh __init__ () ``na paraiméadair seo a leanas:

Tá an bhrí chéanna ag na roghanna go léir gan míniú ar an liosta thuas a dhéanann siad do ghnáth-réimsí Django. Féach an doiciméadú páirce le haghaidh samplaí agus sonraí.

Dífhoirmiú allamuighLink to this heading

Is é an contrárphointe le do mhodh ``__init__ () ``a scríobh ná an modh:meth: ~.field.deconstruct a scríobh. Úsáidtear é le linn: doc: imirce samhail chun a insint le Django conas sampla de do réimse </topics/migrations> nua a thógáil agus é a laghdú go foirm shraitheach - go háirithe, cad iad na hargóintí atá le dul chuig ``__init__ () ``chun é a athchruthú.

Mura gcuir tú aon roghanna breise leis ar bharr an réimse a d'oidhreacht uaidh, ansin ní gá modh nua deconstruct () `a scríobh. ag athrú, áfach, na hargóintí a rith in ``__init__ () ``(mar atá muid i `Handfield), beidh ort na luachanna atá á rith a fhorlíonadh.

Tugann ``deconstruct () ``cúpla de cheithre mhír ar ais: ainm tréith an réimse, cosán iomlán iompórtála an aicme réimse, na hargóintí suímh (mar liosta), agus na hargóintí eochairfhocal (mar dhic). Tabhair faoi deara go bhfuil sé seo difriúil ón modh ``deconstruct () ``: ref: `d'aicmí saincheaptha <custom-deconstruct-method>`a thugann tuple de thrí rud ar ais.

Mar údar réimse saincheaptha, ní gá duit aire a thabhairt faoin gcéad dá luach; tá an cód go léir ag an mbonn rang ``Field` chun ainm tréith agus cosán allmhairithe an réimse a oibriú amach. Caithfidh tú, áfach, aire a thabhairt faoi na hargóintí seasaimh agus eochairfhocal, mar is dócha gurb iad seo na rudaí atá á athrú agat.

Mar shampla, inár rang Handfield táimid i gcónaí ag socrú go foréigeantach max_length in ``__init__ () ``. Feicfidh an modh deconstruct () ``ar an rang bonn ``Field é seo agus déanfaidh sé iarracht é a thabhairt ar ais sna hargóintí eochairfhocal; dá bhrí sin, is féidir linn é a scaoileadh ó na hargóintí eochairfhocal le haghaidh inléiteachta:

Code
from django.db import models


class HandField(models.Field):
    def __init__(self, *args, **kwargs):
        kwargs["max_length"] = 104
        super().__init__(*args, **kwargs)

    def deconstruct(self):
        name, path, args, kwargs = super().deconstruct()
        del kwargs["max_length"]
        return name, path, args, kwargs

Má chuireann tú argóint eochairfhocal nua leis, ní mór duit cód a scríobh i deconstruct () ``a chuireann a luach isteach i `kwargs` tú féin. Ba chóir duit an luach ó `kwargs ``a fhágáil freisin nuair nach gá staid an réimse a athchóiriú, mar shampla nuair a bhíonn an luach réamhshocraithe á n-úsáid:

Code
from django.db import models


class CommaSepField(models.Field):
    "Implements comma-separated storage of lists"

    def __init__(self, separator=",", *args, **kwargs):
        self.separator = separator
        super().__init__(*args, **kwargs)

    def deconstruct(self):
        name, path, args, kwargs = super().deconstruct()
        # Only include kwarg if it's not the default
        if self.separator != ",":
            kwargs["separator"] = self.separator
        return name, path, args, kwargs

Tá samplaí níos casta thar raon feidhme an doiciméad seo, ach cuimhnigh - le haghaidh aon chumraíocht de do shampla Réimse, ní mór deconstruct () ``argóintí a thabhairt ar ais ar féidir leat a chur chuig ``__init__ chun an stát sin a athchóiriú.

Tabhair aird bhreise má shocraíonn tú luachanna réamhshocraithe nua d'argóintí sa sáraicme ``Field`; ba mhaith leat a chinntiú go bhfuil siad san áireamh i gcónaí, seachas imeacht má ghlacann siad leis an seanluach réamhshocraithe.

Ina theannta sin, déan iarracht luachanna a thabhairt ar ais mar argóintí seasaimh a sheachaint; nuair is féidir, cuir luachanna ar ais mar argóintí eochairfhocal chun Má athraíonn tú ainmneacha rudaí níos minice ná a seasamh i liosta argóintí an tógálaí, b'fhéidir gur fearr leat suíomh, ach coinnigh i gcuimhne go mbeidh daoine ag athtógáil do réimse ón leagan sraitheach ar feadh tamaill go leor (blianta b'fhéidir), ag brath ar fad a bheidh do imirce.

Is féidir leat torthaí an dífhoirmithe a fheiceáil trí imirce a chuimsíonn an réimse a chuimsíonn, agus is féidir leat dífhoirmiú a thástáil i dtástálacha aonaid tríd an réimse a dhífhoirmiú agus a athchóiriú:

Code
name, path, args, kwargs = my_field_instance.deconstruct()
new_instance = MyField(*args, **kwargs)
self.assertEqual(my_field_instance.some_attribute, new_instance.some_attribute)

Tréithe réimse nach mbíonn tionchar ag sainmhíniúLink to this heading

Is féidir leat Field.non_DB_Attrs a shárú chun tréithe réimse a shaincheapadh nach mbíonn tionchar acu ar shainmhíniú colún. Úsáidtear é le linn imirce samhail chun oibríochtaí gan aon Alterfield a bhrath.

Mar shampla:

Code
class CommaSepField(models.Field):
    @property
    def non_db_attrs(self):
        return super().non_db_attrs + ("separator",)

Athrú bunaicme réimse saincheapthaLink to this heading

Ní féidir leat bunaicme réimse saincheaptha a athrú toisc nach mbraithfidh Django an t-athrú agus ní dhéanfaidh sé imirce dó. Mar shampla, má thosaíonn tú le:

Code
class CustomCharField(models.CharField): ...

agus ansin cinneadh go dteastaíonn uait TextField a úsáid ina ionad, ní féidir leat an fo-rang a athrú mar seo:

Code
class CustomCharField(models.TextField): ...

Ina áit sin, ní mór duit rang réimse saincheaptha nua a chruthú agus do mhúnlaí a nuashonrú chun tagairt a dhéanamh dó:

Code
class CustomCharField(models.CharField): ...


class CustomTextField(models.TextField): ...

Mar a pléadh in:ref: réimsí a bhaint <migrations-removing-model-fields>, ní mór duit an rang bunaidh CustomCharfield a choinneáil chomh fada agus a bhíonn imirceanna agat a thagann tagairt dó.

Do réimse saincheaptha a dhoiciméadúLink to this heading

Mar is gnách, ba cheart duit do chineál réimse a dhoiciméadú, ionas go mbeidh a fhios ag úsáideoirí cad é. Chomh maith le docstring a sholáthar dó, atá úsáideach d'fhorbróirí, is féidir leat ligean d'úsáideoirí an aip riaracháin cur síos gairid ar an gcineál réimse a fheiceáil tríd an bhfeidhmchlár: doc: django.contrib.admin</ref/contrib/admin/admindocs> docs. Chun seo a dhéanamh soláthraíonn téacs tuairisciúil in a:attr: ~field.description tréith aicme do réimse saincheaptha. Sa sampla thuas, is é 'Lámh cártaí (stíl droichead) 'an cur síos a thaispeánann an t-iarratas admindocs` ar ``lámha láimhse.

Sa taispeán:mod: django.contrib.admindocs, tá cur síos ar an réimse idirphóilte le réimse. __dict__ a ligeann don tuairisc argóintí an réimse a ionchorprú. Mar shampla, is é an cur síos dag:class: ~django.db.models.charfield:

Code
description = _("String (up to %(max_length)s)")

Modhanna úsáideachaLink to this heading

Nuair a bheidh do fho-aicme: Class: ~Django.db.Models.Field cruthaithe agat, b'fhéidir go smaoinfidh tú ar chúpla modh caighdeánach a shárú, ag brath ar iompar do réimse. Tá an liosta modhanna thíos in ord tábhachtachta thart ar laghdú, mar sin tosaigh ón mbarr.

Cineálacha sonraí saincheapthaLink to this heading

Abair gur chruthaigh tú cineál saincheaptha PostgreSQL ar a dtugtar mytype. Is féidir leat fo-aicme Field agus an modh:meth: ~field.db_type a chur i bhfeidhm, mar sin:

Code
from django.db import models


class MytypeField(models.Field):
    def db_type(self, connection):
        return "mytype"

Nuair a bheidh MyTypeField agat, is féidir leat é a úsáid in aon mhúnla, díreach cosúil le haon chineál ``Field` eile:

Code
class Person(models.Model):
    name = models.CharField(max_length=80)
    something_else = MytypeField()

Má tá sé mar aidhm agat feidhmchlár agnasach bunachar sonraí a thógáil, ba cheart duit cuntas a thabhairt ar dhifríochtaí i gcineálacha colún bunachar sonraí. Mar shampla, tugtar timestamp ``ar an gcineál colún dáta/ama i PostgreSQL, agus tugtar `datetime` ar an gcolún céanna i MySQL. Is féidir leat é seo a láimhseáil i modh a:meth: ~field.db_type tríd an tréith connection.vendor a sheiceáil. Is iad na hainmneacha díoltóra ionsuite atá ann faoi láthair ná: sqlite`, postgresql`, mysql, agus oracle.

Mar shampla:

Code
class MyDateField(models.Field):
    def db_type(self, connection):
        if connection.vendor == "mysql":
            return "datetime"
        else:
            return "timestamp"

Glaonn Django ar na modhanna: Meth: ~Field.DB_TYPE agus:meth: ~Field.rel_DB_TYPE nuair a thógann an creat na ráitis CREATE TABLE d'iarratas - is é sin, nuair a chruthaíonn tú do tháblaí den chéad uair. Tugtar ar na modhanna freisin agus clásal WHERE á thógáil lena n-áirítear an réimse samhail - is é sin, nuair a aisghabhann tú sonraí ag baint úsáide as modhanna QuerySet mar get () ``, ``filter (), agus ```eisiamh () ``agus bíonn an réimse samhail mar argóint.

Glacann roinnt cineálacha colún bunachar sonraí le paraiméadair, mar shampla CHAR (25) ``, áit a léiríonn an paraiméadar ```25 fad uasta an cholúin. I gcásanna mar seo, tá sé níos solúbtha má shonraítear an paraiméadar sa tsamhail seachas a bheith crua-chódaithe sa mhodh db_type () `. Mar shampla, ní bheadh sé mórán ciall go mbeadh ``CharmaxLength25field a bheith agat, a thaispeántar anseo:

Code
# This is a silly example of hard-coded parameters.
class CharMaxlength25Field(models.Field):
    def db_type(self, connection):
        return "char(25)"


# In the model:
class MyModel(models.Model):
    # ...
    my_field = CharMaxlength25Field()

Is é an bealach níos fearr chun é seo a dhéanamh ná an paraiméadar a dhéanamh inshonraithe ag am reatha - ie, nuair a bhíonn an rang ag teacht isteach. Chun sin a dhéanamh, cuir Réimse i bhfeidhm. __init__ () `, mar sin:

Code
# This is a much more flexible example.
class BetterCharField(models.Field):
    def __init__(self, max_length, *args, **kwargs):
        self.max_length = max_length
        super().__init__(*args, **kwargs)

    def db_type(self, connection):
        return "char(%s)" % self.max_length


# In the model:
class MyModel(models.Model):
    # ...
    my_field = BetterCharField(25)

Faoi dheireadh, má éilíonn do cholún socrú SQL fíor-chasta, filleadh None ó: meth: .db_type. Cuirfidh sé seo faoi deara go scipeálfaidh cód cruthaithe SQL Django thar an réimse seo. Tá tú freagrach ansin as an colún a chruthú sa tábla ceart ar bhealach éigin eile, ach tugann sé seo bealach duit chun a rá le Django dul amach as an mbealach.

Glaonn an modh: Meth: ~Field.rel_DB_Type trí réimsí mar ForeignKey agus OneTooneField a thugann pointe chuig réimse eile chun a gcineálacha sonraí colún bunachar sonraí a chinneadh. Mar shampla, má tá UnsignedaUtofield agat, teastaíonn na heochracha eachtracha uait a chuireann in iúl chuig an réimse sin chun an cineál sonraí céanna a úsáid:

Code
# MySQL unsigned integer (range 0 to 4294967295).
class UnsignedAutoField(models.AutoField):
    def db_type(self, connection):
        return "integer UNSIGNED AUTO_INCREMENT"

    def rel_db_type(self, connection):
        return "integer UNSIGNED"

Luachanna a thiontú go rudaí PythonLink to this heading

Má dhéileálann do rang saincheap:class: ~Field le struchtúir sonraí atá níos casta ná teaghráin, dátaí, sláimhreacha nó snámha, ansin b'fhéidir go mbeidh ort athraithe:meth: ~field.from_db_value agus:meth: ~field.to_python.

Má tá sé i láthair don fho-aicme réimse, glaofar ``from_db_value () ``i ngach imthosca nuair a luchtaítear na sonraí ón mbunachar sonraí, lena n-áirítear i gcomhiomlánacha agus:meth: ~django.db.models.query.queryset.values glaonna.

Tugtar ``to_python () ``trí dhísheirialú agus le linn an modh:meth: ~django.db.models.model.clean a úsáidtear ó fhoirmeacha.

Mar riail ghinearálta, ba cheart go ndéanfadh ``to_python () ``déileáil go grásta le haon cheann de na hargóintí seo a leanas:

  • Sampla den chineál ceart (m.sh., Lám` inár sampla leanúnach).

  • A shreang

  • None (má cheadaíonn an réimse Null=True)

Inár rang Handfield, táimid ag stóráil na sonraí mar réimse VARCHAR sa bhunachar sonraí, mar sin ní mór dúinn a bheith in ann teaghráin agus None a phróiseáil sa from_db_value () ``. I ``to_python () ``, mór dúinn cásanna ``Hand a láimhseáil freisin:

Code
import re

from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext_lazy as _


def parse_hand(hand_string):
    """Takes a string of cards and splits into a full hand."""
    p1 = re.compile(".{26}")
    p2 = re.compile("..")
    args = [p2.findall(x) for x in p1.findall(hand_string)]
    if len(args) != 4:
        raise ValidationError(_("Invalid input for a Hand instance"))
    return Hand(*args)


class HandField(models.Field):
    # ...

    def from_db_value(self, value, expression, connection):
        if value is None:
            return value
        return parse_hand(value)

    def to_python(self, value):
        if isinstance(value, Hand):
            return value

        if value is None:
            return value

        return parse_hand(value)

Tabhair faoi deara go gcuirimid sampla Hand ar ais i gcónaí ó na modhanna seo. Sin an cineál réada Python ba mhaith linn a stóráil i dtréith an tsamhail.

Maidir le ``to_python () ``, má théann aon rud mícheart le linn tiontaithe luacha, ba cheart duit eisceacht a:exc: ~Django.Core.Exceptions.ValidationError a ardú.

Rudaí Python a thiontú go luachanna ceisteannaLink to this heading

Ós rud é go n-éilíonn tiontú ar bhonn sonraí a úsáid ar an dá bhealach, má théann tú róth:meth: ~field.from_db_value caithfidh tú ró-ride:meth: ~field.get_prep_value chun rudaí Python a thiontú ar ais go luachanna fiosrúcháin.

Mar shampla:

Code
class HandField(models.Field):
    # ...

    def get_prep_value(self, value):
        return "".join(
            ["".join(l) for l in (value.north, value.east, value.south, value.west)]
        )

Luachanna ceist a thiontú go luachanna bunacharLink to this heading

Caithfidh roinnt cineálacha sonraí (mar shampla, dátaí) a bheith i bhformáid shonrach sula bhféadfaidh cúltaca bunachar sonraí iad a úsáid. :meth: ~Field.get_DB_Prep_Value is é an modh inar chóir na tiontaithe sin a dhéanamh. Cuirtear an nasc sonrach a úsáidfear don cheist ar aghaidh mar pharaiméadar nasc. Ligeann sé seo duit loighic chomhshó cúltaca a úsáid má tá sé ag teastáil.

Mar shampla, úsáideann Django an modh seo a leanas dá: aicme: BinaryField:

Code
def get_db_prep_value(self, value, connection, prepared=False):
    value = super().get_db_prep_value(value, connection, prepared)
    if value is not None:
        return connection.Database.Binary(value)
    return value

Sa chás go dteastaíonn tiontú speisialta ag teastáil ó do réimse saincheaptha agus é a shábháil nach bhfuil mar an gcéanna leis an gcomhshó a úsáidtear le haghaidh gnáthpharaiméadair fiosrúcháin, is féidir leat athraithe:meth: ~field.get_db_prep_save.

Luachanna réamhphróiseála sula sábháilLink to this heading

Más mian leat an luach a réamhphróiseáil díreach sula sábhálann tú, is féidir leat: meth: ~field.pre_save a úsáid. Mar shampla, úsáideann Django's:Class: ~Django.db.Models.DateTimeField an modh seo chun an tréith a shocrú i gceart sa chás de:attr: ~django.db.models.dateField.auto_now nó:attr: ~Django.db.Models.DateField.Auto_Now_Add.

Má dhéanann tú an modh seo a shárú, ní mór duit luach na tréithe a thabhairt ar ais ag an deireadh. Ba cheart duit tréith an tsamhail a nuashonrú freisin má dhéanann tú aon athruithe ar an luach ionas go bhfeicfidh cód ina bhfuil tagairtí don tsamhail an luach ceart i gcónaí.

An réimse foirme do réimse samhail a shonrúLink to this heading

Chun an réimse foirme a úsáideann:: class: ~django.forms.ModelForm a shaincheapadh, is féidir leat: meth: ~Field.FormField a shárú.

Is féidir an rang réimse foirme a shonrú trí na hargóintí form_class agus roghnaí_form_class; úsáidtear an dara ceann má tá roghanna sonraithe sa réimse, an chéad cheann eile a shlí eile. Mura gcuirtear na hargóintí seo ar fáil, úsáidfear :class: ~django.forms.charfield nó:class: ~django.forms.typedChoiceField.

Seoltar an foclóir kwargs ar fad díreach chuig modh __init__() réimse na foirme. De ghnáth, níl le déanamh ach réamhshocrú maith a shocrú don argóint form_class (agus b'fhéidir choices_form_class) agus ansin láimhseáil bhreise a tharmligean chuig an rang tuismitheora. D’fhéadfadh go n-éileodh sé seo leat réimse foirme saincheaptha (agus fiú giuirléid foirme) a scríobh. Féach an doiciméid foirmeacha le haghaidh faisnéise faoi seo.

If you wish to exclude the field from the ModelForm, you can override the formfield() method to return None.

Ag leanúint lenár sampla leanúnach, is féidir linn an modh: meth: ~field.formField a scríobh mar:

Code
class HandField(models.Field):
    # ...

    def formfield(self, **kwargs):
        # Exclude the field from the ModelForm when some condition is met.
        some_condition = kwargs.get("some_condition", False)
        if some_condition:
            return None

        # Set up some defaults while letting the caller override them.
        defaults = {"form_class": MyFormField}
        defaults.update(kwargs)
        return super().formfield(**defaults)

Glacann sé seo leis go bhfuil aicme réimse MyFormField iompórtáilte againn (a bhfuil a ghiuirléid réamhshocraithe féin aige). Ní chlúdaíonn an doiciméad seo na sonraí maidir le réimsí foirme saincheaptha a scríobh.

Cineálacha réimse ionsuite a aithrisLink to this heading

Má chruthaigh tú modh a:meth: .db_type, ní gá duit a bheith buartha fao:meth: .get_internal_type - ní úsáidfear mórán é. Uaireanta, áfach, bíonn do stóráil bunachar sonraí cosúil le cineál réimse éigin eile, ionas gur féidir leat loighic réimse eile sin a úsáid chun an colún ceart a chruthú.

Mar shampla:

Code
class HandField(models.Field):
    # ...

    def get_internal_type(self):
        return "CharField"

Is cuma cén cúltaca bunachar sonraí atá á úsáid againn, ciallóidh sé seo go gcruthaíonn: djadmin: migrate agus orduithe SQL eile an cineál colún ceart chun sreang a stóráil.

If: Meth: .get_internal_type filleann sreang nach bhfuil ar eolas ag Django don chúltaca bunachar sonraí atá á úsáid agat - is é sin, níl sé le feiceáil i django.db.backends. <db_name>.base.databaseWrapper.Data_Types -- úsáidfidh an serializer an sreang fós, ach cuirfidh an modh réamhshocraithe: meth: ~Field.db_type ar ais None. Féach an doiciméadú de:meth: ~field.db_type ar chúiseanna a d'fhéadfadh sé seo a bheith úsáideach. Is smaoineamh úsáideach é teaghrán tuairisciúil a chur isteach mar chineál an réimse don serializer má tá tú riamh ag baint úsáide as an aschur serializer in áit éigin eile, lasmuigh de Django.

Sonraí réimse a thiontú le haghaidh sraitheadhLink to this heading

Chun an chaoi a ndéantar na luachanna a shraitheadh ag serializer a shaincheapadh, is féidir leat: meth: ~field.value_to_string a shárú. Úsáid:Meth: ~ Field.value_from_Object is é an bealach is fearr chun luach an réimse a fháil roimh shraitheadh. Mar shampla, ós rud é go n-úsáideann Handfield teaghráin lena stóráil sonraí ar aon nós, is féidir linn roinnt cód tiontaithe atá ann cheana a athúsáid:

Code
class HandField(models.Field):
    # ...

    def value_to_string(self, obj):
        value = self.value_from_object(obj)
        return self.get_prep_value(value)

Roinnt comhairle ginearáltaLink to this heading

Is próiseas deacair is féidir le réimse saincheaptha a scríobh, go háirithe má tá tiontaithe casta á dhéanamh agat idir do chineálacha Python agus do bhunachar sonraí agus formáidí sraitheach. Seo cúpla leid chun rudaí a dhéanamh níos réidh:

  1. Féach ar na réimsí Django atá ann cheana (in:source: django/db/models/fields/__init__.py) le haghaidh inspioráide. Déan iarracht réimse a fháil atá cosúil leis an méid atá uait agus é a leathnú beagán, in ionad réimse iomlán nua a chruthú ón tús.

  2. Cuir modh __str__ () ``ar an rang atá ag timfhilleadh suas mar réimse. go leor áiteanna ann ina bhfuil iompar réamhshocraithe an chód réimse glaoch ar ``str () ``ar an luach. (Sna samplaí atá againn sa doiciméad seo, is sampla ``Láimh a bheadh luach `, Láimhe`, Láimhe ``, ``Láimhse). Mar sin má athraíonn do mhodh ``__str__ () ``go huathoibríoch go foirm teaghrán do réad Python, is féidir leat a lán oibre a shábháil duit féin.

Ag scríobh fo-aicme FilefieldLink to this heading

Chomh maith leis na modhanna thuas, tá cúpla riachtanas speisialta eile ag réimsí a dhéileálann le comhaid nach mór a chur san áireamh. Is féidir le formhór na meicnic a sholáthraíonn “Filefield”, amhail stóráil agus aisghabháil bunachar sonraí a rialú, fanacht gan athrú, ag fágáil fo-aicmí chun déileáil leis an dúshlán tacú le cineál áirithe comhad.

Soláthraíonn Django aicme Comhad ``, a úsáidtear mar sheachfhreastalaí d'ábhar agus oibríochtaí an chomhaid. Is féidir é seo a fho-aicmiú chun an chaoi a ndéantar rochtain ar an gcomhad a shaincheapadh, agus na modhanna atá ar fáil. ina chónaí ag `django.db.models.fields.fil</ref/files/file> es, agus mínítear a iompar réamhshocraithe in:doc: doiciméadú comhad.

Nuair a chruthaítear fo-aicme de Comhad `, ní mór a rá don fho-aicme nua FileField é a úsáid. Chun é sin a dhéanamh, sannadh an fo-aicme nua File don tréith speisialta `attr_class den fho-aicme FileField.

Cúpla moladhLink to this heading

Chomh maith leis na sonraí thuas, tá cúpla treoirlínte ann ar féidir leo éifeachtúlacht agus inléiteacht chód an réimse a fheabhsú go mór.

  1. Is sampla iontach é an fhoinse do ImageField` féin Django (in:source: django/db/models/fields/files.py) de conas fo-aicme Filefield chun tacú le cineál áirithe comhad, mar go n-ionchorpraíonn sé na teicnící go léir a thuairiscítear thuas.

  2. Tréithe comhaid taisce nuair is féidir. Ós rud é go bhféadfar comhaid a stóráil i gcórais stórála iargúlta, d'fhéadfadh go gcosnóidh siad am breise, nó fiú airgead, ní gá é sin i gcónaí. Nuair a aisghabtar comhad chun roinnt sonraí faoina ábhar a fháil, taisce an oiread de na sonraí sin agus is féidir chun an líon uaireanta caithfear an comhad a aisghabháil ar ghlaonna ina dhiaidh sin ar an bhfaisnéis sin a laghdú.