Skip to main content
A Pydantic model is a class that defines the structure of your data. It specifies what fields exist and what types they should be:
This model says: “A User has a name (string), email (string), and age (integer).”

Dataclasses vs Pydantic

Python has built-in dataclasses for defining data structures:
The @dataclass decorator generates an __init__ method from your type hints. Without it, you get TypeError: User() takes no arguments because a plain class with annotations doesn’t accept constructor arguments. Dataclasses give you a clean syntax for data containers, but they don’t validate anything. The type hints are just documentation. Pydantic models look similar but actually enforce the types:
For most projects, just use Pydantic. You get validation, serialization, and JSON Schema generation with minimal overhead. Pydantic v2 is fast enough that the performance difference rarely matters.

Creating instances

Create a model instance by passing data to it:
Pydantic validates the data when you create the instance. Invalid data raises an error immediately.

Validation in action

Try passing invalid data:
Error:
The error tells you exactly what went wrong and where.

Automatic type coercion

Pydantic is smart about type conversion. It converts compatible types automatically:
This is useful when working with form data or API responses where numbers come as strings.

Required vs optional fields

Fields without defaults are required:

Default values

Set defaults for fields that usually have a common value:

Converting to a dictionary

Use model_dump() to convert a model to a dictionary:
This is useful when you need to:
  • Send data to an API
  • Store in a database
  • Serialize to JSON

Converting to JSON

Use model_dump_json() to get a JSON string:

Creating from a dictionary

Two ways to create a model from a dictionary:
Both validate the data. Use **data for simple cases. Use model_validate() when you need options like strict=True. This is the pattern you’ll use most often: receiving data as a dictionary (from an API, database, or file) and validating it into a model.

Models as type hints

Pydantic models work as type hints in your functions. This gives you IDE autocomplete and type checking:
This makes your code self-documenting. When you see user: User in a function signature, you know exactly what data to pass.

Real-world example

Here’s a model for handling API responses:

Common mistakes

Forgetting type hints

Mutable default values

In regular Python classes, = [] is dangerous because all instances share the same list. Pydantic handles this correctly and creates a new list for each instance:
You can also use Field(default_factory=list) if you prefer being explicit, but it’s not required in Pydantic.

Strict mode

By default, Pydantic coerces compatible types (like "25" to 25). If you want to disable this and require exact types, use strict mode:
model_config is a special attribute name that Pydantic looks for. ConfigDict holds configuration options for the model. For most use cases, the default lax mode is what you want.

Learn more

Practice & Exercises

To reinforce what you’ve learned, practice with these interactive notebooks:

Follow-Along Practice

Practice defining dataclasses, building your first Pydantic BaseModel, testing type coercion, handling ValidationErrors, and working with strict vs lax validation modes.💻 VS Code | 🚀 Colab | 📥 Download

Practice Exercises

Test your knowledge with hands-on exercises defining customized dataclasses, verifying object equality, and creating Pydantic schemas that support type coercion.💻 VS Code | 🚀 Colab | 📥 Download

What’s next?

Now you know how to create basic models. Next, let’s learn how to add validation rules and constraints to your fields.

Validation and Fields

Learn how to add validation rules and constraints to your fields.