Мне нужно получить доступ к my_key
в Pydantic Field
, как показано ниже:
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?
Я пытался посмотреть, что содержит self
, например self.__dict__
, но не смог найти. Можно ли вообще получить доступ my_key
?
Мне это нужно для моей конечной точки FastAPI.
Поле не принимает произвольных аргументов, чего именно вы пытаетесь добиться, возможно есть более подходящее решение.
По вашему другому вопросу x — это атрибут класса, определение которого можно найти в self.__class__.__fields__
, а его значение экземпляра можно найти, вызвав self.x
Используя ваш ответ, мне удалось получить доступ к значению: self.__class__.__fields__['x'].field_info.extra['my_key']
, спасибо! Это правильный способ сделать это?
Там есть! CompanyFilter.schema()['MyModel']['x']['my_key']
. Спасибо, вы направили меня в правильном направлении. Не могли бы вы адаптировать свой ответ, и я с радостью приму его.
Вы можете сгенерировать представление схемы JSON модели , используя метод BaseModel
.schema()
, а затем положиться на эту функциональность настройки поля, которая:
**
любые другие аргументы ключевого слова (например,examples
) будут добавлены дословно в схему поля
Другими словами, любые другие произвольные аргументы ключевого слова, переданные в Field
, которые не потребляются или не используются Pydantic (или каким-либо пользовательским созданием/экземпляром), будут присутствовать в представлении схемы JSON этого поля.
Итак, в этом случае ваш my_key
должен присутствовать на схеме модели:
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'}}}
^^^^^^^^^^^^
||||||||||||
Затем у вас может быть метод экземпляра, который выглядит следующим образом:
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
Но, поскольку схема модели и определения Field
привязаны к классу, а не к экземпляру, несколько экземпляров будут иметь одинаковое значение:
In [28]: m1 = MyModel()
In [29]: m1.print_field_objects()
7
42
In [30]: m2 = MyModel()
In [31]: m2.print_field_objects()
7
42
Таким образом, было бы точнее сделать его методом класса, поскольку my_key
все равно не изменится с разными значениями поля x
или с разными экземплярами:
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
Мне нужно хранить больше информации в определении поля. Я делаю фильтры, похожие на django-rest-framework. Я храню их там просто для того, чтобы определить мои фильтры более понятным способом.