Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct Field(..., exclude: bool) docs #7214

Merged
merged 1 commit into from Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
69 changes: 2 additions & 67 deletions docs/usage/serialization.md
Expand Up @@ -634,7 +634,7 @@ The same holds for the `model_dump_json` method.
### Model- and field-level include and exclude

In addition to the explicit arguments `exclude` and `include` passed to `model_dump` and `model_dump_json` methods,
we can also pass the `exclude` arguments directly to the `Field` constructor:
we can also pass the `exclude: bool` arguments directly to the `Field` constructor:

Setting `exclude` on the field constructor (`Field(..., exclude=True)`) takes priority over the
`exclude`/`include` on `model_dump` and `model_dump_json`:
Expand All @@ -651,90 +651,25 @@ class User(BaseModel):

class Transaction(BaseModel):
id: str
user: User = Field(exclude={'username'})
value: int = Field(exclude=True)


t = Transaction(
id='1234567890',
user=User(id=42, username='JohnDoe', password='hashedpassword'),
value=9876543210,
)

print(t.model_dump())
#> {'id': '1234567890'}
# TODO: this is wrong! not all of "user" should be excluded
# TODO: do we need to fix the type of the argument to Field? Or do we want to just remove that functionality?
print(t.model_dump(include={'id': True, 'value': True})) # (1)!
#> {'id': '1234567890'}
```

1. `value` excluded from the output because it excluded in `Field`.

Note that while merging settings, `exclude` entries are merged by computing the "union" of keys, while `include`
entries are merged by computing the "intersection" of keys.

The resulting merged exclude settings:

```py
from pydantic import BaseModel, Field, SecretStr


class User(BaseModel):
id: int
username: str # overridden by explicit exclude
password: SecretStr = Field(exclude=True)


class Transaction(BaseModel):
id: str
user: User
value: int


t = Transaction(
id='1234567890',
user=User(id=42, username='JohnDoe', password='hashedpassword'),
value=9876543210,
)

print(t.model_dump(exclude={'value': True, 'user': {'username'}}))
#> {'id': '1234567890', 'user': {'id': 42}}
```

are the same as using merged include settings as follows:

```py
from pydantic import BaseModel, SecretStr


class User(BaseModel):
id: int
username: str
password: SecretStr


class Transaction(BaseModel):
id: str
user: User
value: int


t = Transaction(
id='1234567890',
user=User(id=42, username='JohnDoe', password='hashedpassword'),
value=9876543210,
)

print(t.model_dump(include={'id': True, 'user': {'id'}}))
#> {'id': '1234567890', 'user': {'id': 42}}
```

## `model_copy(...)`

`model_copy()` allows models to be duplicated (with optional updates), which is particularly useful when working with
frozen models. See the [API docs for `model_copy`][pydantic.main.BaseModel.model_copy] for more
information.
`model_copy()` allows models to be duplicated (with optional updates), which is particularly useful when working with frozen models.

Example:

Expand Down
4 changes: 3 additions & 1 deletion pydantic/main.py
Expand Up @@ -240,7 +240,9 @@ def model_construct(cls: type[Model], _fields_set: set[str] | None = None, **val
return m

def model_copy(self: Model, *, update: dict[str, Any] | None = None, deep: bool = False) -> Model:
"""Returns a copy of the model.
"""Usage docs: https://docs.pydantic.dev/2.2/usage/serialization/#model_copy

Returns a copy of the model.

Args:
update: Values to change/add in the new model. Note: the data is not validated
Expand Down