Reputation: 476
I need to access my_key
in a Pydantic Field
, as shown below:
class MyModel(BaseModel):
x: str = Field(default=None, my_key=7)
def print_field_objects(self):
for obj in self.something_something: # What do I use here
print(obj.my_key) # ... so that i can use my_key?
I tried to see what self
contains, like self.__dict__
but I wasn't able to find it. Is it even possible to access my_key
?
I need it for my FastAPI endpoint.
Upvotes: 0
Views: 1331
Reputation: 29546
You can generate the model's JSON Schema representation using the BaseModel
's .schema()
method, and then rely on this functionality of Field
customization that:
**
any other keyword arguments (e.g.examples
) will be added verbatim to the field's schema
In other words, any other arbitrary keyword arguments passed to Field
that isn't consumed or used by Pydantic (or by any custom creation/instantiation) would be present in that field's JSON Schema representation.
So, in this case, your my_key
should be present on the model's schema:
In [4]: class MyModel(BaseModel):
...: x: str = Field(default=None, my_key=7)
...:
In [5]: MyModel.schema()
Out[5]:
{'title': 'MyModel',
'type': 'object',
'properties': {'x': {'title': 'X', 'my_key': 7, 'type': 'string'}}}
^^^^^^^^^^^^
||||||||||||
You can then have an instance method that looks like this:
In [21]: class MyModel(BaseModel):
...: x: str = Field(default=None, my_key=7)
...: y: int = Field(default=1, my_key=42)
...:
...: def print_field_objects(self):
...: for field_name, field in self.schema()["properties"].items():
...: print(field["my_key"])
...:
In [22]: m1 = MyModel()
In [23]: m1.print_field_objects()
7
42
But, since a model's schema and Field
definitions are tied to the class, not the instance, multiple instances would have the same value:
In [28]: m1 = MyModel()
In [29]: m1.print_field_objects()
7
42
In [30]: m2 = MyModel()
In [31]: m2.print_field_objects()
7
42
So, it would be more accurate to make it a class method instead, since my_key
won't change anyway with different values of the field x
or with different instances:
In [35]: class MyModel(BaseModel):
...: x: str = Field(default=None, my_key=7)
...: y: int = Field(default=1, my_key=42)
...:
...: @classmethod
...: def print_field_objects(cls):
...: for field_name, field in cls.schema()["properties"].items():
...: print(field_name, field.get("my_key"))
...:
In [36]: MyModel.print_field_objects()
x 7
y 42
Upvotes: 2
Reputation: 22449
Field doesn't take arbitrary arguments, what exactly are you trying to achieve, perhaps there's a more appropriate solution.
Per your other question, x is a class attribute, whose definition can be found in self.__class__.__fields__
, while its instance value can be found by calling self.x
Upvotes: 1