georgebv / drf-pydantic

Use pydantic with the Django REST framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Looks like model_validator is not called during drf validation

djbios opened this issue · comments

Repro:

from drf_pydantic import BaseModel
from pydantic import model_validator


class A(BaseModel):
    @model_validator(mode='after')
    def qwe(self):
        assert False

A.drf_serializer(data={}).is_valid(raise_exception=True)  # Nothing happens :(

This is expected - you are validating payload using DRF serializer, not using the pydantic model.

After model class declaration (not instantiation), DRF serializer and pydanitc model become fully separate objects. The only things that carry over between the two are fields and field constraints. Field validators, model validators, properties, or any other custom code you write for your pydantic models cannot be ported to DRF serializer.

I appreciate the clarification. I understand the design choice better now. However, this behavior does pose a challenge for those of us who rely on Pydantic's field validators for comprehensive validation. Without these validators being executed during the DRF is_valid call, the main advantage of reducing redundancy by automatically creating DRF serializers from Pydantic models is diminished.

Is it possible to integrate Pydantic's validation logic within the DRF serializer process in future versions? This would greatly enhance the utility of your library by fully leveraging the strengths of both Pydantic and DRF. Thank you for considering this feedback.

Thank you for your suggestion. I understand what you are asking for and perhaps this could be implemented, but with making a custom subclass of a DRF serializer to couple the models together. We need to agree on the expected behavior: what should happen when you call is_valid on DRF model? Should it also validate data against the pydantic model? Which one should run first? Are there any other behaviors in DRF serializers which should trigger (re-)validation of the parent pydantic model?

Thank you for considering this enhancement. The most logical behavior would be to mimic Pydantic's validation process within the DRF serializer. Specifically, when is_valid is called on the DRF serializer, it should also validate the data against the Pydantic model.

Whether to continue using DRF's internal validation (by mapping Pydantic fields to DRF fields) or to rely solely on Pydantic's validation (acting as a wrapper for Pydantic fields) remains an open question.

Either way, any validation errors should be raised in a way that conforms to DRF standards, including appropriate HTTP response codes and error response bodies structured as dictionaries with fields and errors.