Bailíochtú foirm agus réimseLink to this heading

Tarlaíonn bailíochtú foirme nuair a ghlantar na sonraí. Más mian leat an próiseas seo a shaincheapadh, tá áiteanna éagsúla ann chun athruithe a dhéanamh, agus gach ceann acu ag freastal ar chuspóir difriúil. Reáchtáiltear trí chineál modhanna glantacháin le linn próiseála foirme. De ghnáth déantar iad seo a fhorghníomhú nuair a ghlaonn tú ar an modh is_valid () ``ar fhoirm. rudaí eile ann a d'fhéadfadh glanadh agus bailíochtú a spreagadh freisin (rochtain a fháil ar an tréith ``earráidí ``nó glaoch ar `full_clean () go díreach), ach de ghnáth ní bheidh siad ag teastáil.

Go ginearálta, is féidir le haon mhodh glantacháin ValidationError` a ardú fadhb ann leis na sonraí atá á phróiseáil aige, ag cur an fhaisnéis ábhartha chuig an tógálaí ``ValidationError`. :ref: `Féach thíos <raising-validation-error>`le haghaidh an dea-chleachtas maidir le ``ValidationError a ardú. Mura n-ardaítear aon ValidationError, ba cheart don modh na sonraí glanta (normalaithe) a thabhairt ar ais mar réad Python.

Is féidir an chuid is mó de bhailíochtú a dhéanamh ag baint úsáide as bailíodóirí `_ - cúntóirí is féidir a athúsáid. Is feidhmeanna (nó glaonna) iad bailíochtóirí a thógann argóint amháin agus a ardaíonn ``ValidationError` ar ionchur neamhbhailí. Déantar bailíochtóirí a reáchtáil tar éis modhanna to_python agus validate an réimse a ghlaoch.

Roinntear bailíochtú foirme ina roinnt céimeanna, ar féidir iad a shaincheapadh nó a shárú:

  • Is é an modh to_python () ``ar `Réimse an chéad chéim i ngach bailíochtú. Cuireann sé an luach ar chineál sonraí ceart agus ardaíonn sé ValidationError mura féidir é sin a dhéanamh. Glacann an modh seo leis an luach amh ón ngiuirléid agus filleann sé an luach tiontaithe ar ais. Mar shampla, iompróidh Floatfield na sonraí ina float` Python nó ardóidh ValidationError.

  • Láimhseálann an modh validate () ``ar `Réimse bailíochtú réamh-shonrach nach bhfuil oiriúnach do bhailíochtóir. Tógann sé luach a cuireadh iallach ar chineál sonraí ceart agus ardaíonn sé ValidationError ar aon earráid. Ní thugann an modh seo aon rud ar ais agus níor cheart dó an luach a athrú. Ba chóir duit é a shárú chun loighic bhailíochtaithe nach féidir leat nó nach dteastaíonn uait bailíochtóir a chur isteach.

  • Ritheann an modh run_validators () ``ar `Réimse bailíochtóirí uile an réimse agus comhiomlánann sé na hearráidí go léir ina ValidationError amháin. Níor chóir go gcaithfidh tú an modh seo a shárú.

  • Tá an modh clean () ``ar fho-aicme ``Field freagrach as to_python (), validate () `, agus run_validators () a reáchtáil san ord ceart agus a n-earráidí a iomadú. Má ardaíonn aon cheann de na modhanna, ag am ar bith, ValidationError, stopann an bailíochtú agus ardaítear an earráid sin. Tugann an modh seo na sonraí glan ar ais, a chuirtear isteach ansin isteach i bhfoclóir cleaned_data na foirme.

  • <fieldname>Glaítear ar an modh clean_ () `ar fho-aicme foirme -- ina gcuirtear ainm tréith réim <fieldname>se na foirme in ionad ``. Déanann an modh seo aon ghlanadh atá sonrach don tréith áirithe sin, nach mbaineann leis an gcineál réimse atá ann. Ní chuirtear an modh seo ar bith paraiméadair. Beidh ort luach an réimse a fheiceáil suas i self.cleaned_data ``agus cuimhnigh gur réad Python é ag an bpointe seo, ní an teaghrán bunaidh a chuirtear isteach san fhoirm (beidh sé i ``cleaned_data` toisc gur ghlanadh an modh réimse ginearálta ``clean () ``thuas, na sonraí cheana féin).

    Mar shampla, dá dteastaíonn uait a bhailíochtú go raibh ábhar charfield ar a dtugtar serialnumber uathúil, bheadh clean_serialnumber () ``an áit cheart chun é seo a dhéanamh. Ní theastaíonn réimse ar leith uait (is `Charfield é), ach teastaíonn píosa bailíochtaithe atá sonrach le réimse foirme uait agus, b'fhéidir, na sonraí a ghlananach/normalú.

    Cuireann luach tuairisceáin an mhodha seo in ionad an luach atá ann cheana i cleaned_data `, mar sin caithfidh sé a bheith luach an réimse ó cleaned_data` (fiú mura n-athraigh an modh seo é) nó luach nua glantaithe.

  • Is féidir le modh clean () ``an fho-aicme foirme bailíochtú a dhéanamh a éilíonn rochtain ar réimsí iolracha foirme. Seo an áit a bhféadfá seiceálacha a chur isteach mar “má sholáthraítear réimse ``A, caithfidh seoladh ríomhphoist bailí a bheith i réimse B”. Is féidir leis an modh seo foclóir go hiomlán difriúil a thabhairt ar ais más mian leis, a úsáidfear mar an cleaned_data.

    Ós rud é go bhfuil na modhanna bailíochtaithe réimse á reáchtáil faoin am a dtugtar clean () ``, rochtain agat freisin ar thréith ``earráidí na foirme ina bhfuil na hearráidí go léir a ardaítear trí ghlanadh réimsí aonair.

    Note that any errors raised by your Form.clean() override will not be associated with any field in particular. They go into a special "field" (called __all__), which you can access via the non_field_errors() method if you need to. If you want to attach errors to a specific field in the form, you need to call add_error().

    Tabhair faoi deara freisin go bhfuil breithnithe speisialta ann agus an modh `clean () `de fho-aicme ``ModelForm ``a shárú. (féach an:ref: `Doiciméadú ModelForm <overriding-modelform-clean-method>`le haghaidh tuilleadh eolais)

These methods are run in the order given above, one field at a time. That is, for each field in the form (in the order they are declared in the form definition), the Field.clean() method (or its override) is run, then clean_<fieldname>(). Finally, once those two methods are run for every field, the Form.clean() method, or its override, is executed whether or not the previous methods have raised errors.

Tá samplaí de gach ceann de na modhanna seo ar fáil thíos.

Mar a luadh, is féidir le haon cheann de na modhanna seo Error Validationer a ardú. Maidir le haon réimse, má ardaíonn an modh Field.clean () ```Error validation, ní ghlaofar aon mhodh glantacháin réimsiú-shonrach. Mar sin féin, déantar na modhanna glantacháin do gach réimse atá fágtha i bhfeidhm fós.

“Earráid Bailíochtaithe” a ardúLink to this heading

D'fhonn teachtaireachtaí earráide a dhéanamh solúbtha agus éasca le frithdhíriú, smaoinigh ar na treoirlínte

  • Soláthar earráid tuairisciúil ``cód ``don tógálaí:

    Code
    # Good
    ValidationError(_("Invalid value"), code="invalid")
    
    # Bad
    ValidationError(_("Invalid value"))
    
  • Ná cuir athróga isteach sa teachtaireacht; bain úsáid as sealbhóirí agus argóint `params' an tógálaí:

    Code
    # Good
    ValidationError(
        _("Invalid value: %(value)s"),
        params={"value": "42"},
    )
    
    # Bad
    ValidationError(_("Invalid value: %s") % value)
    
  • Úsáid eochracha mapála in ionad formáidiú suímh. Cuireann sé seo ar chumas na hathróga a chur in aon ord nó iad a fhágáil ar fad agus an teachtaireacht á athscríobh:

    Code
    # Good
    ValidationError(
        _("Invalid value: %(value)s"),
        params={"value": "42"},
    )
    
    # Bad
    ValidationError(
        _("Invalid value: %s"),
        params=("42",),
    )
    
  • Fill an teachtaireacht le gettext chun aistriúchán a chumasú:

    Code
    # Good
    ValidationError(_("Invalid value"))
    
    # Bad
    ValidationError("Invalid value")
    

Ag cur é ar fad le chéile:

Code
raise ValidationError(
    _("Invalid value: %(value)s"),
    code="invalid",
    params={"value": "42"},
)

Is gá go háirithe na treoirlínte seo a leanúint má scríobhann tú foirmeacha in-athúsáidte, réimsí foirme

Cé nach mholtar, má tá tú ag deireadh an slabhra bailíochtaithe (ie do mhodh `glan () `foirm) agus má tá a fhios agat nach gcaithfidh tú riam do theachtaireacht earráide a shárú is féidir leat an rud is lú fós a roghnú:

Code
ValidationError(_("Invalid value: %s") % value)

<django.forms.Form.errors.as_json () >Baineann na modhanna: Meth: Form.errors.as_data () agus:meth: Form.error<django.forms.Form.errors.as_data () > s.as_json () leas mór as ValidationErrors atá le feiceáil go hiomlán (le hainm cód `agus foclóir `params).

Earráidí iomadúla a ardúLink to this heading

Má aimsíonn tú earráidí iolracha le linn modh glantacháin agus má theastaíonn uait iad go léir a chomharthú chuig an aighdeoir foirme, is féidir liosta earráidí a chur ar aghaidh chuig an tógálaí ValidationError.

Mar atá thuas, moltar liosta de chásanna ValidationError a rith le cód ``\ s agus `params ach oibreoidh liosta teaghráin freisin:

Code
# Good
raise ValidationError(
    [
        ValidationError(_("Error 1"), code="error1"),
        ValidationError(_("Error 2"), code="error2"),
    ]
)

# Bad
raise ValidationError(
    [
        _("Error 1"),
        _("Error 2"),
    ]
)

Bailíochtú a úsáid i gcleachtasLink to this heading

Mhínigh na hailt roimhe seo conas a oibríonn bailíochtú i gcoitinne le haghaidh Ós rud é go bhféadfadh sé a bheith níos éasca uaireanta rudaí a chur i bhfeidhm trí gach gné atá in úsáid a fheiceáil, seo sraith samplaí beaga a úsáideann gach ceann de na gnéithe roimhe seo.

Bailíochtóirí a úsáidLink to this heading

Tacaíonn réimsí foirme (agus samhail) Django le húsáid feidhmeanna fóntais agus ranganna ar a dtugtar bailíochtóirí. Is réad nó feidhm inghlaonta é bailíochtaitheoir a thógann luach agus nach dtugann aon rud ar ais má tá an luach bailí nó má ardaíonn a:exc: ~django.core.exceptions.validationError mura bhfuil. Is féidir iad seo a chur chuig tógálaí réimse, trí argóint validators ``an réimse, a shainiú ar aicme:class: `~django.forms.field` féin leis an tréith ``default_validators.

Is féidir bailíochtóirí a úsáid chun luachanna taobh istigh den réimse a bhailíochtú, déanaimis féachaint ar ``Slugfield` Django:

Code
from django.core import validators
from django.forms import CharField


class SlugField(CharField):
    default_validators = [validators.validate_slug]

Mar a fheiceann tú, is Charfield` é ``Slugfield le bailíochtóir saincheaptha a bhailíochnaíonn go gcloíonn an téacs curtha isteach do roinnt rialacha carachtar. Is féidir é seo a dhéanamh freisin ar an sainmhíniú allamuigh mar sin:

Code
slug = forms.SlugField()

atá coibhéiseach le:

Code
slug = forms.CharField(validators=[validators.validate_slug])

Common cases such as validating against an email or a regular expression can be handled using existing validator classes available in Django. For example, validators.validate_slug is an instance of a RegexValidator constructed with the first argument being the pattern: ^[-a-zA-Z0-9_]+\Z. See the section on writing validators to see a list of what is already available and for an example of how to write a validator.

Glanadh réamhshocraithe réimseLink to this heading

Déanaimis réimse foirme saincheaptha a chruthú ar dtús a bhailíochnaíonn a ionchur ná sreang ina bhfuil seoltaí ríomhphoist scartha le camóg. Breathnaíonn an rang iomlán mar seo:

Code
from django import forms
from django.core.validators import validate_email


class MultiEmailField(forms.Field):
    def to_python(self, value):
        """Normalize data to a list of strings."""
        # Return an empty list if no input was given.
        if not value:
            return []
        return value.split(",")

    def validate(self, value):
        """Check if value consists only of valid emails."""
        # Use the parent's handling of required fields, etc.
        super().validate(value)
        for email in value:
            validate_email(email)

Beidh na modhanna seo á reáchtáil ag gach foirm a úsáideann an réimse seo sula bhféadfar aon rud eile a dhéanamh le sonraí an réimse. Is glanadh é seo atá sonrach don chineál seo réimse, beag beann ar an gcaoi a n-úsáidtear é ina dhiaidh sin.

Cruthaímid Foirm Teagmhála chun a thaispeáint conas a úsáideann tú an réimse seo:

Code
class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField()
    contact_email = forms.EmailField()
    recipients = MultiEmailField()
    urgent = forms.BooleanField(required=False)

Úsáid Multiemailfield cosúil le haon réimse foirme eile. Nuair a ghlaofar an modh is_valid () ``ar an bhfoirm, reáchtálfar an modh ``multiemailfield.clean () mar chuid den phróiseas glantacháin agus glaóidh sé, ina dhiaidh sin, na modhanna saincheaptha to_python () ``agus ``validate ().

Glanadh tréith réimse ar leithLink to this heading

Continuing on from the previous example, suppose that in our ContactForm, we want to make sure that the recipients field only contains addresses that are @example.com. This is validation that is specific to our form, so we don't want to put it into the general MultiEmailField class. Instead, we write a cleaning method that operates on the recipients field, like so:

Code
from django import forms
from django.core.exceptions import ValidationError


class ContactForm(forms.Form):
    # Everything as before.
    ...

    def clean_recipients(self):
        data = self.cleaned_data["recipients"]
        if not all(email.endswith("@example.com") for email in data):
            raise ValidationError("All recipients must be @example.com.")

        # Always return a value to use as the new cleaned data, even if
        # this method didn't change it.
        return data

Réimsí a ghlanadh agus a bhailíochtú atá ag brath ar a chéileLink to this heading

Suppose we add another requirement to our contact form: if the urgent field is True, the subject must contain "help". We are performing validation on more than one field at a time, so the form's clean() method is a good spot to do this. Notice that we are talking about the clean() method on the form here, whereas earlier we were writing a clean() method on a field. It's important to keep the field and form difference clear when working out where to validate things. Fields are single data points, forms are a collection of fields.

Faoin am a dtugtar modh clean () ``ar an bhfoirm, beidh na modhanna glan réimse aonair go léir á reáchtáil (an chuid roimhe seo), mar sin déanfar ``self.cleaned_data daonra le haon sonraí a tháinig maireachtáil go dtí seo. Mar sin ní mór duit cuimhneamh freisin a cheadú go mb'fhéidir nár mhair na réimsí atá tú ag iarraidh a bhailíochtú sna seiceálacha réimse aonair tosaigh.

Tá dhá bhealach ann chun aon earráidí ón gcéim seo a thuairisciú. Is dócha gurb é an modh is coitianta an earráid a thaispeáint ag barr na foirme. Chun earráid den sórt sin a chruthú, is féidir leat ValidationError a ardú ón modh ``clean () ``. Mar shampla:

Code
from django import forms
from django.core.exceptions import ValidationError


class ContactForm(forms.Form):
    # Everything as before.
    ...

    def clean(self):
        cleaned_data = super().clean()
        urgent = cleaned_data.get("urgent")
        subject = cleaned_data.get("subject")

        if urgent and subject:
            # Only do something if both fields are valid so far.
            if "help" not in subject:
                raise ValidationError(
                    "Must put 'help' in the subject for urgent requests."
                )

Sa chód seo, má ardaítear an earráid bailíochtaithe, taispeánfaidh an fhoirm teachtaireacht earráide ag barr na foirme (de ghnáth) ag cur síos ar an bhfadhb. Is earráidí neamh-réimse iad earráidí den sórt sin, a thaispeántar sa teimpléad le {{form.non_field_errors}}.

Cinntíonn an glao chuig super () .clean () ``sa chód samplaí go gcoinnítear aon loighic bailíochtaithe i ranganna tuismitheoirí. foirm eile ag d'oidhreacht nach gcuireann foclóir ``cleaned_data ``ar ais ina modh ``clean () (is roghnach é sin a dhéanamh), ansin ná sannadh cleaned_data do thoradh an ghlaonna super () ``agus bain úsáid as ``self.cleaned_data ina ionad:

Code
def clean(self):
    super().clean()
    urgent = self.cleaned_data.get("urgent")
    ...

The second approach for reporting validation errors might involve assigning the error message to one of the fields. In this case, let's assign an error message to both the "subject" and "urgent" rows in the form display. Be careful when doing this in practice, since it can lead to confusing form output. We're showing what is possible here and leaving it up to you and your designers to work out what works effectively in your particular situation. Our new code (replacing the previous sample) looks like this:

Code
from django import forms


class ContactForm(forms.Form):
    # Everything as before.
    ...

    def clean(self):
        cleaned_data = super().clean()
        urgent = cleaned_data.get("urgent")
        subject = cleaned_data.get("subject")

        if urgent and subject and "help" not in subject:
            self.add_error(
                "subject", "Must put 'help' in the subject for urgent requests."
            )
            self.add_error(
                "urgent", "Must not mark urgent unless 'help' is in the subject."
            )

Is féidir leis an dara argóint de add_error () ``a bheith ina shreang, b'fhéidir mar shampla de ``ValidationError. Féach:ref: raising-validation-error le haghaidh tuilleadh sonraí. Tabhair faoi deara go mbaineann add_error () ``an réimse go huathoibríoch ó ``cleaned_data.