django-ninja
django-ninja copied to clipboard
Fields which have a resolve method in ModelSchema are no longer parsed in put requests.
Describe the bug Fields which have a resolve method in ModelSchema are no longer parsed in put requests.
Versions:
- Python version: 3.10
- Django version: 4.2.7
- Django-Ninja version: 1.0.1
- Pydantic version: 2.5.1
In Ninja v0 I had
class MyModelSchema(ModelSchema):
my_field_from_model_2: str
class Config:
model = models.MyModel
model_fields = ['id', 'my_field_from_model_1']
@staticmethod
def resolve_my_field_from_model_2(obj):
# code to resolve field would be here, just return it as it is for the example
return obj.my_field_from_model_2
I switch class Config to Meta and model_fields to fields for ninja v1.
In v1 each field which has a custom resolve method (e.g my_field_from_model_2) is no longer included in the payload.dict() when doing a PUT request. In v0 this worked and the field was included.
Is this on purpose no longer available per default and is there any way to activate this again? I could not really find any model_config in pydantic which allows that.
Quickfix would be to use different schemas for GET and PUT, but it would be nice if it could be done with the same one.
@21adrian1996
hard to tell... could you show the code you have for v1 ?
The code for version 1 is basically the same with the new naming:
class MyModelSchema(ModelSchema):
model_config = ConfigDict(
extra='allow'
)
my_field_from_model_2: str
class Meta:
model = models.MyModel
fields = ['id', 'my_field_from_model_1']
@staticmethod
def resolve_my_field_from_model_2(obj):
# code to resolve field would be here, just return it as it is for the example
return obj.my_field_from_model_2
Note: model_config does not seem to change this.
Then the API is something like
@router.put('/mymodel')
def put_mymodel(request, payload: MyModelSchema):
pl = payload.dict()
where all fields which have a resolve_ method are not included in pl.
@21adrian1996
so this is a bit backward incompatible thing - in pydantic2 all orm-mode objects converted from dict to objects
in new version - object that you got in resolver is matching the the input data (like in this case it's dict as it was an JSON input)
so you should change your code like this:
@staticmethod
def resolve_my_field_from_model_2(obj: dict):
return obj["my_field_from_model_2"] # <-- !!!