2025, Oct 18 07:31

क्रॉस‑फील्ड वैलिडेशन: Pydantic में पासवर्ड कन्फर्मेशन त्रुटि को सही फ़ील्ड से जोड़ें

जानें कैसे Pydantic में क्रॉस‑फील्ड वैलिडेशन लागू करें: after फील्ड वैलिडेटर और ValidationInfo से पासवर्ड कन्फर्मेशन बेमेल त्रुटि को सही फ़ील्ड से जोड़ें.

क्रॉस‑फील्ड वैलिडेशन एक आम आवश्यकता है: दो इनपुट अलग‑अलग रूप से मान्य होते हैं, लेकिन साथ रखने पर अमान्य हो सकते हैं। इसका क्लासिक उदाहरण पासवर्ड कन्फर्मेशन है। लंबाई और उपस्थिति के फील्ड‑लेवल चेक ठीक काम करते हैं, लेकिन जब मान मेल नहीं खाते, तो त्रुटि अक्सर किसी खास फील्ड से अलग होकर दिखती है। उद्देश्य यह है कि त्रुटि को कन्फर्मेशन फील्ड से जोड़ा जाए ताकि क्लाइंट को ठीक‑ठीक पता चले कि क्या सुधारना है।

समस्या को पुनः उत्पन्न करना

निम्न मॉडल दोनों इनपुट के लिए लंबाई और रिक्तता की जाँच करता है और फिर मॉडल‑लेवल चेक में उन्हें तुलना करता है। तर्क सही है, लेकिन बेमेल की त्रुटि किसी खास फील्ड से बँधती नहीं है।

from pydantic import BaseModel, Field, field_validator, model_validator
class CredentialInput(BaseModel):
    pwd: str = Field(..., min_length=8, max_length=128)
    pwd_repeat: str = Field(..., min_length=8, max_length=128)
    @field_validator("pwd")
    def ensure_pwd_present(cls, v: str) -> str:
        if not v.strip():
            raise ValueError("Password required")
        return v
    @field_validator("pwd_repeat")
    def ensure_pwd_repeat_present(cls, v: str) -> str:
        if not v.strip():
            raise ValueError("Confirm Password Required")
        return v
    @model_validator(mode="before")
    def verify_pair_equality(cls, vals):
        p = vals.get("pwd")
        r = vals.get("pwd_repeat")
        if p != r:
            raise ValueError("Passwords does not match")
        return vals

क्या हो रहा है और क्यों

समानता की जाँच “before” वैलिडेटर में मॉडल‑लेवल पर चलती है। इसका अर्थ है कि त्रुटि पूरे मॉडल के लिए उठती है, किसी विशेष फील्ड के लिए नहीं; इसलिए वह कन्फर्मेशन इनपुट जैसे किसी एक पाथ से नहीं जुड़ेगी। दूसरी ओर, फील्ड‑लेवल वैलिडेटर अपनी संबद्ध फील्ड पर ही त्रुटि रिपोर्ट करते हैं। बेमेल को कन्फर्मेशन इनपुट पर दिखाने के लिए तुलना उसी इनपुट की फील्ड‑लेवल वैलिडेशन के रूप में की जानी चाहिए।

समाधान: सह‑डेटा तक पहुँच वाले after फील्ड वैलिडेटर का इस्तेमाल करें

After‑वैलिडेटर info आर्ग्युमेंट के जरिए पहले से पार्स हो चुकी फील्ड्स तक पहुँच सकते हैं। mode="after" में कन्फर्मेशन फील्ड को वैलिडेट करके और info.data से प्राथमिक पासवर्ड पढ़कर, बेमेल की त्रुटि स्वाभाविक रूप से कन्फर्मेशन फील्ड से बँध जाती है।

from pydantic import BaseModel, Field, field_validator
from pydantic_core.core_schema import ValidationInfo
class CredentialInput(BaseModel):
    pwd: str = Field(..., min_length=8, max_length=128)
    pwd_repeat: str = Field(..., min_length=8, max_length=128)
    @field_validator("pwd")
    @classmethod
    def ensure_pwd_present(cls, v: str) -> str:
        if not v.strip():
            raise ValueError("Password required")
        return v
    @field_validator("pwd_repeat")
    @classmethod
    def ensure_pwd_repeat_present(cls, v: str) -> str:
        if not v.strip():
            raise ValueError("Confirm Password Required")
        return v
    @field_validator("pwd_repeat", mode="after")
    @classmethod
    def ensure_match(cls, value: str, info: ValidationInfo) -> str:
        if value != info.data["pwd"]:
            raise ValueError("Passwords do not match")
        return value

यह तरीका दस्तावेज़ित पैटर्न को ही दोहराता है: टार्गेट फील्ड के पार्स होते ही after‑वैलिडेटर चलते हैं और info.data से सहोदर फील्ड्स पढ़ने देते हैं, जिससे क्रॉस‑फील्ड त्रुटियों को किसी एक इनपुट से जोड़ना संभव हो जाता है।

यह क्यों मायने रखता है

त्रुटि का स्थान मात्र सौंदर्य की बात नहीं है। API और फ्रंटएंड सटीक इनपुट को हाइलाइट करने के लिए पूर्वानुमेय एरर पाथ पर निर्भर करते हैं। सामान्य मॉडल‑स्तरीय त्रुटि क्लाइंट को अंदाज़ा लगाने पर मजबूर करती है कि कौन सा फील्ड ठीक किया जाए, जबकि फील्ड‑स्कोप्ड त्रुटि सीधे और क्रियाशील संदेश देती है। पासवर्ड कन्फर्मेशन फ्लो में बेमेल को कन्फर्मेशन फील्ड से जोड़ना अपेक्षित और उपयोगकर्ता‑अनुकूल व्यवहार है।

विस्तृत उपयोग के लिए टिप्पणियाँ

यही तकनीक तब भी लागू होती है जब एक ही अनुरोध में कई तुलनाएँ करनी हों। After‑वैलिडेटर info.data के जरिए पार्स्ड डेटा पढ़ सकते हैं। ध्यान देने योग्य है कि यदि कई after वैलिडेटर हों, तो संभव है कि किसी एक को info.data में सभी फील्ड दिखाई दें, जबकि दूसरे को वह खाली मिले। वैलिडेशन स्टेप्स व्यवस्थित करते समय इसे ध्यान में रखें।

निष्कर्ष

जब आपको क्रॉस‑फील्ड जाँच का असर किसी खास फील्ड पर चाहिए, तो तुलना को mode="after" वाले फील्ड‑लेवल वैलिडेटर में ले आएँ और दूसरी फील्ड तक info.data के जरिए पहुँचें। इससे त्रुटि इच्छित इनपुट से जुड़ी रहती है, क्लाइंट‑साइड UX बेहतर होता है और यह दस्तावेज़ित वैलिडेशन प्रवाह से मेल खाता है।

यह लेख StackOverflow पर प्रश्न (लेखक: Mr. Kenneth) और ken के उत्तर पर आधारित है।