Итак, прежде всего, цель этого вопроса — получить больше знаний о том, возможно ли это и какова практика борьбы с вредителями.
есть 3 типа пользователей
7, 6 — обычные пользователи
5,4 — издатели
3,2 — менеджеры
1 — администратор
Я использую эту функцию для выделения user_role
И вот первый вопрос.
Я буду часто использовать эту функцию и подумаю об этом.
Я могу просто добавить user_role в токен JWT, но я так думаю собираюсь создать проблему с безопасностью, верно?
async def check_permission(
permission: int,
current_user: user_dependecny,
db: db_dependecny,
error: bool = True,
):
current_user_role = (
db.query(user.User).filter(user.User.id == current_user.id).first().user_role
)
# 7= reader, 6= Pro_reader,
# 5= publisher, 4= editor,
# 3= small_manager, 2= big_manager, 1= admin
if current_user_role permission:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="Do not have premisson."
)
к основному вопросу в заголовке
попытка использовать множество data_type для одного параметра возможна с помощью Union
< pre class="lang-py Prettyprint-override">from typing import Annotated, Union, cast
type1 = None
type2 = None
type3 = None
var: Union[type1,type2,type3]
Я впервые попробовал это с помощью get enpoint на model_response, и это сработало.
код ниже возвращает пользовательские данные на основе вашей user_role и для этого мне понадобились 3 разные базовые модели
@router.get(
"/{user_id}/", response_model=Union[SelfUserInfo, ManagerUserInfo, UserInfo]
)
async def read_user(
user_id: int,
db: db_dependecny,
current_user: user_dependecny,
):
db_user = db.query(user.User).filter(user.User.id == user_id).first()
if db_user is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="user is not found"
)
if await check_permission(3, current_user, db, error=False) == True:
user_data = ManagerUserInfo(
username=db_user.username,
avatar_url=db_user.avatar_url,
user_role=db_user.user_role,
email=db_user.email,
country_id=db_user.country_id,
last_login=db_user.last_login,
date_joined=db_user.date_joined,
is_verfied=db_user.is_verfied,
state=db_user.state,
is_staff=db_user.is_staff,
is_superuser=db_user.is_superuser,
)
return user_data
else:
if current_user.id == user_id:
user_data = SelfUserInfo(
username=db_user.username,
avatar_url=db_user.avatar_url,
user_role=db_user.user_role,
email=db_user.email,
country_id=db_user.country_id,
last_login=db_user.last_login,
date_joined=db_user.date_joined,
is_verfied=db_user.is_verfied,
)
return user_data
else:
user_data = UserInfo(
username=db_user.username,
avatar_url=db_user.avatar_url,
user_role=db_user.user_role,
)
return user_data
мой второй вопрос по поводу этого кода: он не соответствует практике борьбы с вредителями.
в последнем коде у меня возникла проблема
моя проблема в том, что тип user_data всегда SelfUserUpdate
особенно первый тип
user_data: Union[SelfUserUpdate, ManagerUserUpdate, AdminUserUpdate],
как это исправить и правильно ли делать это таким образом вместо того, чтобы
создавать три разные конечные точки.
@router.put("/{user_id}/")
async def Update_user(
user_id: int,
current_user: user_dependecny,
db: db_dependecny,
user_data: Union[SelfUserUpdate, ManagerUserUpdate, AdminUserUpdate],
):
db_user = db.query(user.User).filter(user.User.id == user_id).first()
if db_user is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="user is not found"
)
if await check_permission(1, current_user, db, error=False) == True:
# Admin edit user
db_user.username = user_data.username
db_user.avatar_url = user_data.avatar_url
db_user.email = user_data.email
db_user.country_id = user_data.country_id
db_user.user_role = user_data.user_role
db_user.state = user_data.state
db_user.is_staff = user_data.is_staff
db_user.is_verfied = user_data.is_verfied
db_user.is_superuser = user_data.is_superuser
db.commit()
db.refresh(db_user)
return user_data
elif check_permission(3, current_user, db, error=False) == True:
# Manager edit user
db_user.username = user_data.username
db_user.avatar_url = user_data.avatar_url
db_user.email = user_data.email
db_user.country_id = user_data.country_id
db_user.user_role = user_data.user_role
db_user.state = user_data.state
db_user.is_staff = user_data.is_staff
db.commit()
db.refresh(db_user)
return user_data
elif current_user.id == user_id:
# current user edit him self
db_user.username = user_data.username
db_user.avatar_url = user_data.avatar_url
db_user.email = user_data.email
db_user.country_id = user_data.country_id
db.commit()
db.refresh(db_user)
return user_data
else:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="You can't change This user.",
)
Подробнее здесь: https://stackoverflow.com/questions/787 ... n-1-type-o
Возможно ли, чтобы одна конечная точка put имела параметр, имеющий более 1 типа в fastapi, pydantic ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение