]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
:memo: Fix docs clarification about dict unwrapping
authorSebastián Ramírez <tiangolo@gmail.com>
Mon, 14 Jan 2019 19:01:34 +0000 (23:01 +0400)
committerSebastián Ramírez <tiangolo@gmail.com>
Mon, 14 Jan 2019 19:01:34 +0000 (23:01 +0400)
in extra-models and simple-oauth2 #7

docs/tutorial/extra-models.md
docs/tutorial/security/simple-oauth2.md

index ad35ffeefd35bc512b99110143533c64241a2269..08507d90025d40836d77488fdf9c64038e621586 100644 (file)
@@ -19,11 +19,67 @@ Here's a general idea of how the models could look like with their password fiel
 {!./src/extra_models/tutorial001.py!}
 ```
 
-#### About `**user_dict`
+### About `**user_in.dict()`
 
-`UserInDB(**user_dict)` means:
-    
-Pass the keys and values of the `user_dict` directly as key-value arguments, equivalent to:
+#### Pydantic's `.dict()`
+
+`user_in` is a Pydantic model of class `UserIn`.
+
+Pydantic models have a `.dict()` method that returns a `dict` with the model's data.
+
+So, if we create a Pydantic object `user_in` like:
+
+```Python
+user_in = UserIn(username="john", password="secret", email="john.doe@example.com")
+```
+
+and then we call:
+
+```Python
+user_dict = user_in.dict()
+```
+
+we now have a `dict` with the data in the variable `user_dict` (it's a `dict` instead of a Pydantic model object).
+
+And if we call:
+
+```Python
+print(user_dict)
+```
+
+we would get a Python `dict` with:
+
+```Python
+{
+    'username': 'john',
+    'password': 'secret',
+    'email': 'john.doe@example.com',
+    'full_name': None,
+}
+```
+
+#### Unwrapping a `dict`
+
+If we take a `dict` like `user_dict` and pass it to a function (or class) with `**user_dict`, Python will "unwrap" it. It will pass the keys and values of the `user_dict` directly as key-value arguments.
+
+So, continuing with the `user_dict` from above, writing:
+
+```Python
+UserInDB(**user_dict)
+```
+
+Would result in something equivalent to:
+
+```Python
+UserInDB(
+    username="john",
+    password="secret",
+    email="john.doe@example.com",
+    full_name=None,
+)
+```
+
+Or more exactly, using `user_dict` directly, with whatever contents it might have in the future:
 
 ```Python
 UserInDB(
@@ -34,7 +90,28 @@ UserInDB(
 )
 ```
 
-And then adding the extra `hashed_password=hashed_password`, like in:
+#### A Pydantic model from the contents of another
+
+As in the example above we got `user_dict` from `user_in.dict()`, this code:
+
+```Python
+user_dict = user_in.dict()
+UserInDB(**user_dict)
+```
+
+would be equivalent to:
+
+```Python
+UserInDB(**user_in.dict())
+```
+
+...because `user_in.dict()` is a `dict`, and then we make Python "unwrap" it by passing it to `UserInDB` prepended with `**`.
+
+So, we get a Pydantic model from the data in another Pydantic model.
+
+#### Unrapping a `dict` and extra keywords
+
+And then adding the extra keyword argument `hashed_password=hashed_password`, like in:
 
 ```Python
 UserInDB(**user_in.dict(), hashed_password=hashed_password)
@@ -65,7 +142,7 @@ And these models are all sharing a lot of the data and duplicating attribute nam
 
 We could do better.
 
-We can declare a `Userbase` model that serves as a base for our other models. And then we can make subclasses of that model that inherit its attributes (type declarations, validation, etc).
+We can declare a `UserBase` model that serves as a base for our other models. And then we can make subclasses of that model that inherit its attributes (type declarations, validation, etc).
 
 All the data conversion, validation, documentation, etc. will still work as normally.
 
@@ -77,4 +154,6 @@ That way, we can declare just the differences between the models (with plaintext
 
 ## Recap
 
-Use multiple Pydantic models and inherit freely for each case. You don't need to have a single data model per entity if that entity must be able to have different "states". As the case with the user "entity" with a state including `password`, `password_hash` and no password.
\ No newline at end of file
+Use multiple Pydantic models and inherit freely for each case.
+
+You don't need to have a single data model per entity if that entity must be able to have different "states". As the case with the user "entity" with a state including `password`, `password_hash` and no password.
index 3d5a1a546e309912295d0a5f06fc68d66bdd1310..6aa56767f8a3fd5894df4502bc1f10d44054f10d 100644 (file)
@@ -128,6 +128,9 @@ UserInDB(
 )
 ```
 
+!!! info
+    For a more complete explanation of `**user_dict` check back in <a href="/tutorial/extra-models/#about-user_indict" target="_blank">the documentation for **Extra Models**</a>.
+
 ## Return the token
 
 The response of the `token` endpoint must be a JSON object.