Skip to content
PythonFastAPI

3. Pydantic v2 Tutorial Hindi – Data Validation Master 2026

May 22, 2026 14 min read

नमस्ते दोस्तों!

स्वागत है The Easy Master पर!

क्या आप FastAPI में APIs बना रहे हैं? और data validation के चक्कर में if-else के जंगल में फंस गए हैं? या फिर type hints देखकर सोच रहे हैं – “ये : str लिखने से क्या होगा?”

चलिए मैं आपको एक real story सुनाता हूँ।

जब मैंने पहली बार बिना Pydantic के API बनाई थी, तो मेरा code ऐसा लगता था:

Code
if "name" in data and isinstance(data["name"], str):
    if len(data["name"]) > 0:
        if "age" in data and isinstance(data["age"], int):
            # 50 lines of validation...

बहुत थकाने वाला काम था। फिर मैंने Pydantic सीखा – और मेरी जिंदगी बदल गई। अब validation automatically होती है, errors clear आते हैं, और code 10x cleaner है।

इस Pydantic v2 tutorial Hindi में मैं आपको सब कुछ सिखाऊंगा:

✅ Pydantic क्या है और क्यों जरूरी है
✅ BaseModel से model कैसे बनाएं
✅ Type hints – str, int, float, bool, list, dict
✅ Validation constraints – min_length, max_length, gt, ge
✅ Optional fields और default values
✅ Nested models और complex data structures
✅ Error handling and custom validators
✅ FastAPI के साथ real-world example

और हाँ, end में cheat sheet और practice prompts भी मिलेंगे।

तो चलिए, Pydantic v2 का ये सफर शुरू करते हैं! 🚀



1. Pydantic kya hai? – 1 minute mein samjho

Pydantic ek Python library hai jo data validation aur settings management ke liye use hoti hai.

Simple words mein:
Aap ek class define karte ho – batate ho ki name string hai, age integer hai. Phir jab aap data pass karoge, Pydantic automatically check karega ki data sahi type ka hai ya nahi, aur agar nahi to clear error dega.

FastAPI Pydantic ka heavy use karta hai – request body, query parameters, path parameters – sab kuch Pydantic se validate hota hai.

Example – Bina Pydantic ke:

Code
# Khud likhna padega validation
def create_user(name, age):
    if not isinstance(name, str):
        raise ValueError("Name must be string")
    if not isinstance(age, int):
        raise ValueError("Age must be int")
    if age < 0:
        raise ValueError("Age cannot be negative")
    # ... etc

Example – Pydantic ke saath:

Code
from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int = Field(..., ge=0)  # age >= 0

# Validation automatic!
user = User(name="Rahul", age=25)  # works
user = User(name="Rahul", age=-5)  # error!

Pydantic v2 – New Features

Pydantic v2 2023 mein aaya tha aur v1 se 10x faster hai, better error messages, aur naye validators (e.g., @field_validator instead of @validator). Hum is article mein v2 hi use karenge.


2. Installation aur Setup

Bilkul simple:

Code
pip install pydantic

Ya agar FastAPI ke saath use karna hai (recommended):

Code
pip install fastapi[all]  # isme pydantic already included hai

Check version:

Code
import pydantic
print(pydantic.__version__)  # should be 2.x

3. Pehla Model – BaseModel se shuruaat

Pydantic mein model banane ke liye BaseModel inherit karte hain:

Code
from pydantic import BaseModel

class Student(BaseModel):
    name: str
    roll_no: int
    branch: str
    cgpa: float

# Create instance
s1 = Student(name="Priya", roll_no=101, branch="CSE", cgpa=8.5)
print(s1.name)  # Priya
print(s1.model_dump())  # {'name': 'Priya', 'roll_no': 101, 'branch': 'CSE', 'cgpa': 8.5}

Note: model_dump() v2 mein hai (v1 mein .dict() tha).

Kya validation hoti hai?

Code
# Ye fail hoga - roll_no string diya
s2 = Student(name="Amit", roll_no="abc", branch="ECE", cgpa=7.0)
# ValidationError: roll_no - Input should be a valid integer

Pydantic automatically "abc" ko integer mein convert nahi kar sakta, to error throw karega.

Type coercion (automatic conversion) – Pydantic tries karta hai:

Code
s3 = Student(name="Neha", roll_no="123", branch="ME", cgpa="8.2")
# Kaam kar jayega - "123" -> 123, "8.2" -> 8.2

Personal Experience: Maine ek bar roll_no field string type likh di thi, but database mein integer tha. Pydantic ne automatic convert kar diya – lekin problem tab hui jab mujhe zero-padded roll numbers chahiye the. Toh hamesha proper type choose karo.


4. Type Hints – Data ke Bodyguard

Basic Types

Python TypeValid DataExample
strstring“Rahul”
intinteger25
floatdecimal3.14
boolTrue/FalseTrue
bytesbyte stringb”data”
datetimedate/timedatetime.now()
Python
from datetime import datetime
from pydantic import BaseModel

class Event(BaseModel):
    name: str
    start_time: datetime
    is_active: bool

event = Event(name="Tech Fest", start_time="2026-05-21T10:00:00", is_active=True)
print(event.start_time)  # 2026-05-21 10:00:00 (converted to datetime)

Container Types (list, dict, set)

Code
from typing import List, Dict, Set, Optional
from pydantic import BaseModel

class Course(BaseModel):
    students: List[str]           # list of strings
    scores: Dict[str, int]        # dict with string keys, int values
    tags: Set[str] = set()        # set of strings

c = Course(students=["Rahul", "Priya"], scores={"math": 95, "science": 88}, tags={"python", "fastapi"})

Union Types – Multiple possible types

Code
from typing import Union

class Item(BaseModel):
    value: Union[int, str]  # ya toh int, ya toh string

item1 = Item(value=42)      # valid
item2 = Item(value="hello") # valid
item3 = Item(value=3.14)    # error - float not allowed

5. Validation Constraints – Upar se Extra Protection

Field() function use karke extra constraints laga sakte ho.

Code
from pydantic import BaseModel, Field

class Product(BaseModel):
    name: str = Field(min_length=2, max_length=50)
    price: float = Field(gt=0, le=10000)  # greater than 0, less than or equal 10000
    quantity: int = Field(ge=0, default=0)  # greater than or equal 0, default 0
    code: str = Field(pattern=r"^[A-Z]{3}-\d{4}$")  # regex validation

Explanation:

  • gt = greater than
  • ge = greater than or equal
  • lt = less than
  • le = less than or equal
  • min_length / max_length (strings)
  • pattern (regex for strings)

Example:

Code
prod = Product(name="Laptop", price=50000, code="ABC-1234")  # valid
prod2 = Product(name="L", price=-100)  # Error: name too short, price not gt 0

Field alias – different JSON field name

Code
class User(BaseModel):
    full_name: str = Field(alias="fullName")

user = User(fullName="Rahul Sharma")  # JSON mein "fullName" pass karo
print(user.full_name)  # Rahul Sharma

6. Optional Fields aur Default Values

Default values:

Code
class Config(BaseModel):
    debug: bool = False      # default False
    port: int = 8000         # default 8000

c = Config()                  # debug=False, port=8000
c = Config(debug=True)       # debug=True, port=8000

Optional fields (may be None):

Code
from typing import Optional

class Profile(BaseModel):
    bio: Optional[str] = None      # can be string or None
    age: Optional[int] = None

p1 = Profile()                      # bio=None, age=None
p2 = Profile(bio="Hello")           # bio="Hello", age=None
p3 = Profile(age=25, bio=None)      # valid

Required vs Optional rule:

  • No default → Required field
  • Default value → Optional
  • Optional[type] = None → Optional

7. Nested Models – Models ke andar Models

Real-world data often nested hota hai – e.g., user ke andar address.

Code
from pydantic import BaseModel
from typing import List

class Address(BaseModel):
    street: str
    city: str
    pincode: int

class User(BaseModel):
    name: str
    addresses: List[Address]  # list of Address objects

# Valid data
user_data = {
    "name": "Rahul",
    "addresses": [
        {"street": "MG Road", "city": "Mumbai", "pincode": 400001},
        {"street": "Park Street", "city": "Kolkata", "pincode": 700016}
    ]
}

user = User(**user_data)
print(user.addresses[0].city)  # Mumbai

Deep nesting – example:

Code
class Item(BaseModel):
    name: str
    price: float

class Cart(BaseModel):
    user_id: int
    items: List[Item]
    total: float

cart = Cart(
    user_id=1,
    items=[{"name": "Book", "price": 299}, {"name": "Pen", "price": 50}],
    total=349
)

Pydantic automatically inner models validate karega.


8. Custom Validators (@field_validator, @model_validator)

Kai baar simple constraints kaafi nahi hote – complex logic chahiye. Tab custom validators use karte hain.

@field_validator – single field ke liye

Code
from pydantic import BaseModel, Field, field_validator

class User(BaseModel):
    email: str
    age: int

    @field_validator("email")
    def validate_email(cls, v):
        if "@" not in v or "." not in v:
            raise ValueError("Invalid email format")
        return v.lower()  # normalize to lowercase

    @field_validator("age")
    def validate_age(cls, v):
        if v < 0 or v > 120:
            raise ValueError("Age must be between 0 and 120")
        return v

user = User(email="RAHUL@GMAIL.COM", age=25)
print(user.email)  # rahul@gmail.com

@model_validator – multiple fields together

Code
from pydantic import BaseModel, model_validator

class Order(BaseModel):
    quantity: int
    price_per_unit: float
    discount: float = 0.0

    @model_validator(mode='after')
    def check_total(self):
        total = self.quantity * self.price_per_unit
        if total < self.discount:
            raise ValueError("Discount cannot exceed total amount")
        return self

Note: v2 mein @validator deprecated hai, @field_validator and @model_validator use karo.


9. Error Handling – Errors ko samjho aur handle karo

Jab validation fail hoti hai, Pydantic ValidationError throw karta hai.

Code
from pydantic import BaseModel, ValidationError

class User(BaseModel):
    name: str = Field(min_length=2)
    age: int = Field(ge=0)

try:
    user = User(name="A", age=-5)
except ValidationError as e:
    print(e.errors())  # list of errors
    print(e.json())    # JSON format errors

Example error output:

Code
[
  {
    "type": "string_too_short",
    "loc": ["name"],
    "msg": "String should have at least 2 characters",
    "input": "A"
  },
  {
    "type": "greater_than_equal",
    "loc": ["age"],
    "msg": "Input should be greater than or equal to 0",
    "input": -5
  }
]

User-friendly error handling:
FastAPI automatically ye errors JSON format mein return kar deta hai. Agar manually handle karna hai:

Code
try:
    user = User(name="Rahul", age=25)
except ValidationError as e:
    for err in e.errors():
        field = " -> ".join(str(x) for x in err["loc"])
        print(f"{field}: {err['msg']}")

10. FastAPI ke saath Real Example – User Registration API

Ab sab kuch milake ek complete FastAPI endpoint banate hain:

Code
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field, field_validator, ValidationError
from typing import Optional
from datetime import datetime

app = FastAPI()

class Address(BaseModel):
    street: str = Field(min_length=3)
    city: str = Field(min_length=2)
    pincode: int = Field(ge=100000, le=999999)

class UserRegister(BaseModel):
    username: str = Field(min_length=3, max_length=20, pattern="^[a-zA-Z0-9_]+$")
    email: str
    password: str = Field(min_length=6)
    age: int = Field(ge=18, le=100)
    address: Optional[Address] = None
    registered_at: datetime = Field(default_factory=datetime.now)

    @field_validator("email")
    def validate_email(cls, v):
        if "@" not in v:
            raise ValueError("Invalid email")
        return v.lower()

    @field_validator("password")
    def validate_password_strength(cls, v):
        if not any(char.isdigit() for char in v):
            raise ValueError("Password must contain at least one digit")
        if not any(char.isupper() for char in v):
            raise ValueError("Password must contain at least one uppercase letter")
        return v

@app.post("/register/")
async def register_user(user: UserRegister):
    # Pydantic automatic validation ho chuki hai
    # Yahan database save kar sakte ho
    return {
        "message": "User registered successfully",
        "username": user.username,
        "registered_at": user.registered_at.isoformat()
    }

# Test with invalid data
# POST /register/ with body:
# {
#   "username": "ra",  # too short
#   "email": "test",
#   "password": "weak",
#   "age": 16
# }
# Returns detailed validation error

11. Pydantic v2 vs v1 – Kya badla hai?

FeaturePydantic v1Pydantic v2
.dict()✅❌ (use .model_dump())
.json()✅❌ (use .model_dump_json())
@validator✅❌ (use @field_validator)
@root_validator✅❌ (use @model_validator)
Performanceslower~10x faster (Rust core)
Error messagesbasicmore detailed
Field(alias=...)worksworks, better
model_config classConfig classmodel_config = ConfigDict(...)
Strict modeless supportField(strict=True)

Migration tip: v2 backwards compatible nahi hai fully. Agar existing project hai toh v2 migration guide dekhna.


12. Common Mistakes (aur unka Solution!)

MistakeReasonSolution
Optional[type] bina default ke required rehta haiOptional ka matlab None allowed, but requiredAdd = None → field: Optional[str] = None
.dict() use karna v2 meinv2 mein method change ho gayaUse .model_dump()
Field alias ke saath initializationDirect field name se set karte hoUse alias name in data: {"fullName": "..."}
List validation bhoolnaitems: list se type check hota hai, but element type nahiUse items: List[Item]
Validator mein cls ki jagah self@field_validator classmethod haiFirst argument cls rakho
Circular importsModels ek doosre ko refer kareinUse from __future__ import annotations or string forward ref

Personal Mistake: Maine ek baar Optional[str] likha without default – socha optional hai, but required tha. Toh error aata raha. Uske baad hamesha = None lagata hoon.


13. Resources – Cheat Sheet aur Practice Prompts

Cheat Sheet (Copy-Paste Ready)

Code
# Basic Model
from pydantic import BaseModel, Field, field_validator, model_validator
from typing import Optional, List

class MyModel(BaseModel):
    name: str = Field(min_length=1, max_length=100)
    age: int = Field(ge=0, le=150)
    email: Optional[str] = None
    tags: List[str] = []

    @field_validator("email")
    def validate_email(cls, v):
        if v and "@" not in v:
            raise ValueError("Invalid email")
        return v

    @model_validator(mode='after')
    def check_something(self):
        return self

# Create instance
obj = MyModel(name="Test", age=25)

# Convert to dict
data = obj.model_dump()

# Parse from dict
obj2 = MyModel.model_validate(data)

# Handle errors
try:
    invalid = MyModel(name="", age=-10)
except ValidationError as e:
    print(e.errors())

Practice Prompts

  1. Beginner: Ek Book model banao with fields: title (str), author (str), price (float, positive). Create karo instances and print.
  2. Intermediate: Ek Employee model banao with nested Department model. Add validation: employee salary >= 0, department name length between 2-50.
  3. Advanced: Ek Form model banao with password confirmation – @model_validator use karke check karo ki password and confirm_password match karte hain.

14. FAQ

Q1: Pydantic v1 aur v2 mein main difference kya hai?

v2 up to 10x faster hai, Rust mein core likha gaya hai, error messages better hain, aur validators ka syntax change ho gaya (@field_validator instead of @validator).

Q2: Kya Pydantic database ORM ki jagah use ho sakta hai?

Nahi – Pydantic sirf validation ke liye hai, database queries ke liye SQLAlchemy ya beanie use karo. But Pydantic models ko database models se convert karna common practice hai.

Q3: Field(default=...) aur = value mein kya antar hai?

Field(default=5) use karo jab extra validation chahiye (min_length, gt etc). Agar sirf default chahiye bina constraints ke, =5 simple hai.

Q4: List of custom objects ka validation kaise karein?

items: List[ItemModel] – Pydantic automatically har element ko validate karega.

Q5: Kya Pydantic JSON directly parse kar sakta hai?

Haan, MyModel.model_validate_json(json_string) use karo.

Q6: Secret fields (password) ko serialize se kaise bachayein?

Use SecretStr type from pydantic.types – ye output mein ******** show karega.

Q7: Pydantic validation errors ko custom message kaise do?

ValidationError catch karke custom response banao, ya FastAPI mein HTTPException raise karo. Pydantic error messages directly override nahi kar sakte.


15. Conclusion – Ab aapki baari!

Bahut badhiya! Aapne aaj complete seekh liya:

✅ Pydantic v2 tutorial Hindi mein – BaseModel, type hints, validation constraints
✅ Optional fields, nested models, custom validators
✅ Error handling aur real FastAPI example
✅ Cheat sheet aur practice prompts ready

Pydantic data validation ko effortless banata hai. Ab aap professional APIs likh sakte ho bina if-else validation ke jungle mein phanse.

Aapki aaj ki challenge:
Upar diye gaye practice prompts mein se ek implement karo. Apna code comment mein share karo – main review karunga.

Agla topic kya chahiye?

  • FastAPI Dependency Injection?
  • JWT Authentication in FastAPI?
  • SQLAlchemy + FastAPI Database Integration?

Comment mein batao!

The Easy Master ke saath coding seekhte raho. Happy Validating! 🐍🚀

Resources

Additional Resources

TheEasyMaster

Author at The Easy Master.

Related posts

Leave a Reply

Your email address will not be published. Required fields are marked *