django-ninja-jwt
django-ninja-jwt copied to clipboard
Resolver gets called twice
I am adding a 'user' key to the token claims with the user data including its permissions. Following exactly this I get the tokens with no problem. But resolving the permissions raises a ValidationError, and I realized that the resolver gets called twice: -first time the obj is a User instance and context is None, so no problem for getting the permission list -the second time obj is not a User but a ModelAuthReadSchema instance and context is not None but its user is a AnonymousUser, and here comes the errors
this is my schema for User where AuthModel is just get_user_model()
class ModelAuthReadSchema(ModelSchema):
permissions: List[str] | None
class Meta:
model = AuthModel
fields = ['id', 'username', 'first_name', 'last_name', 'email']
@staticmethod
def resolve_permissions(obj, context):
return get_permissions(obj)
get_permissions is a custom function for getting just business-related permissions
this is the error:
pydantic_core._pydantic_core.ValidationError: 3 validation errors for NinjaResponseSchema
response.refresh
Field required [type=missing, input_value=<DjangoGetter: LoginInput...', username='cccccc')>, input_type=DjangoGetter]
For further information visit https://errors.pydantic.dev/2.6/v/missing
response.access
Field required [type=missing, input_value=<DjangoGetter: LoginInput...', username='cccccc')>, input_type=DjangoGetter]
For further information visit https://errors.pydantic.dev/2.6/v/missing
response.user
Field required [type=missing, input_value=<DjangoGetter: LoginInput...', username='cccccc')>, input_type=DjangoGetter]
For further information visit https://errors.pydantic.dev/2.6/v/missing
this would be the desired output:
{
"refresh": "xxxxxxxxxxx",
"access": "yyyyyyyyyyy",
"user": {
"permissions": [
"app_label1.add_model",
"app_label2.delete_model"
],
"id": 1,
"username": "ccccccc",
"first_name": "",
"last_name": "",
"email": "[email protected]"
}
}
@geclick Sorry I didn't get notified of this issue on time. I am just seeing it now. I am currently looking into it at the moment
@geclick the problem is the resolve_permission method. I don't use the resolver method provided in the Ninja model schema. The problem with that being called twice is likely a problem from pydantic. I know I faced that problem once but I can't remember where.
You can only solve this problem using pydantic model validator at mode='before'. Check the example below.
class ModelAuthReadSchema(ModelSchema):
permissions: List[str] | None
class Meta:
model = AuthModel
fields = ['id', 'username', 'first_name', 'last_name', 'email']
@model_validator(mode="before")
def validate_permission_list(cls, values: DjangoGetter) -> typing.Any:
values = values._obj
if isinstance(values, dict):
# values will have ['id', 'username', 'first_name', 'last_name', 'email']
user = None # add functionality to get the user
permissions = get_permissions(user)
values.update(permissions=permissions)
return values
@geclick the problem is the
resolve_permissionmethod. I don't use theresolvermethod provided in theNinjamodel schema. The problem with that being called twice is likely a problem from pydantic. I know I faced that problem once but I can't remember where.You can only solve this problem using pydantic model validator at mode='before'. Check the example below.
class ModelAuthReadSchema(ModelSchema): permissions: List[str] | None class Meta: model = AuthModel fields = ['id', 'username', 'first_name', 'last_name', 'email'] @model_validator(mode="before") def validate_permission_list(cls, values: DjangoGetter) -> typing.Any: values = values._obj if isinstance(values, dict): # values will have ['id', 'username', 'first_name', 'last_name', 'email'] user = None # add functionality to get the user permissions = get_permissions(user) values.update(permissions=permissions) return values
tnks
@geclick can you close this issue if the problem is resolved?