fix: make UserUpdateForm fields optional to allow partial user updates

Fixes #23424

Previously, the PATCH /{user_id}/update endpoint required all fields
(role, name, email, profile_image_url) even when only updating one.
This caused a validation error when callers only passed a single field.

Make all non-password fields Optional with None defaults. The router
now only updates fields that are explicitly provided, leaving the rest
unchanged.
This commit is contained in:
theshivam7 2026-04-07 23:43:58 +05:30
parent c40ea7f29d
commit 8462426be0
No known key found for this signature in database
GPG key ID: 8ECBA284C12CAA51
2 changed files with 22 additions and 13 deletions

View file

@ -247,15 +247,17 @@ class UserRoleUpdateForm(BaseModel):
class UserUpdateForm(BaseModel):
role: str
name: str
email: str
profile_image_url: str
role: Optional[str] = None
name: Optional[str] = None
email: Optional[str] = None
profile_image_url: Optional[str] = None
password: Optional[str] = None
@field_validator('profile_image_url')
@classmethod
def check_profile_image_url(cls, v: str) -> str:
def check_profile_image_url(cls, v: Optional[str]) -> Optional[str]:
if v is None:
return v
return validate_profile_image_url(v)

View file

@ -573,7 +573,7 @@ async def update_user_by_id(
detail=ERROR_MESSAGES.ACTION_PROHIBITED,
)
if form_data.role != 'admin':
if form_data.role is not None and form_data.role != 'admin':
# If the primary admin is trying to change their own role, prevent it
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
@ -590,7 +590,7 @@ async def update_user_by_id(
user = Users.get_user_by_id(user_id, db=db)
if user:
if form_data.email.lower() != user.email:
if form_data.email is not None and form_data.email.lower() != user.email:
email_user = Users.get_user_by_email(form_data.email.lower(), db=db)
if email_user:
raise HTTPException(
@ -607,15 +607,22 @@ async def update_user_by_id(
hashed = get_password_hash(form_data.password)
Auths.update_user_password_by_id(user_id, hashed, db=db)
Auths.update_email_by_id(user_id, form_data.email.lower(), db=db)
updated_user = Users.update_user_by_id(
user_id,
{
if form_data.email is not None:
Auths.update_email_by_id(user_id, form_data.email.lower(), db=db)
update_data = {
k: v
for k, v in {
'role': form_data.role,
'name': form_data.name,
'email': form_data.email.lower(),
'email': form_data.email.lower() if form_data.email is not None else None,
'profile_image_url': form_data.profile_image_url,
},
}.items()
if v is not None
}
updated_user = Users.update_user_by_id(
user_id,
update_data,
db=db,
)