React Native FastAPI - 422 Axios调用时出现无法处理的实体错误

arknldoa  于 2022-12-24  发布在  React
关注(0)|答案(1)|浏览(138)

我对FastAPI很陌生,我很困惑。我试图通过我的API注册一个新用户,但从我的请求中收到这个错误:

{
    "detail": [
        {
            "loc": [
                "body",
                "id"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        },
        {
            "loc": [
                "body",
                "username"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        },
        {
            "loc": [
                "body",
                "password"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        },
        {
            "loc": [
                "body",
                "email"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        },
        {
            "loc": [
                "body",
                "phone_number"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        }
    ]
}

我不确定我做错了什么,或者是前端还是后端的问题。我假设我用pydantic模型接收这个请求的方式有问题,因为我似乎看不到前端的问题。我在前端的post方法看起来像这样:
api.js

import axios from 'axios';

const api = axios.create({
    withCredentials: true,
    baseURL: 'http://localhost:8000'
});

api.interceptors.request.use((config) => {
    config.headers = {
        Accept: 'application/json',
        ContentType: "application/json"
    };

    return config;
});

api.interceptors.response.use(
    (response) => response,
    (error) => {
        return Promise.reject(error);
    },
);

export default api;

我在前端的服务看起来像

function register(user) {
    return api.post('auth/register', user, { withCredentials: true, 'Access-Control-Allow-Origin': '*' })
        .then((response) => response)
        .catch((error) => Promise.reject(error));
}

然后是我真正的方法调用

const handleRegistration = () => {
        setLoading(true);

        let new_user = {
            username: inputs.username,
            password: inputs.password,
            email: inputs.password,
            phone_number: inputs.phone
        }

        AuthService.register(new_user).then(() => {
                setLoading(false);
                navigation.navigate('LoginScreen');
                toast('success', 'Successfully created new account', null);
            },
            (e) => {
                setLoading(false);
                console.log(e.toString());
                toast('error', 'Error creating new account', null);
            })
    }

最后我的python用户BaseModel和API调用如下所示:
user.py

from pydantic import BaseModel, Field
from .document import DocumentBase

class UserBase(BaseModel):
    id: int
    username: str
    password: str
    email: str
    phone_number: str
    documents: list[DocumentBase] = []

    class Config:
        arbitrary_types_allowed = True
        orm_mode = True

auth.py

@router.post("/register")
def register(data: UserBase, _db: Session = Depends(get_db)):
    # querying database to check if user already exist
    user = _db.query(User).filter(User.email == data.email).first()
    if user is not None:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="User with this email already exist"
        )
    new_user = User()
    new_user.username = data.username
    new_user.password = get_hashed_password(data.password)
    new_user.email = data.email
    new_user.phone_number = data.phone_number

    _db.add(new_user)
    _db.commit()
    return new_user

对这个问题有任何见解都将不胜感激

cbeh67ev

cbeh67ev1#

  • API接受来自BaseUser的数据,所以它需要您在那里声明的所有字段,除非它们有默认值。
  • 您是否检查过register方法实际上以JSON发送数据?

第一点的解决方案是创建两个模型:一个用于数据输入,另一个用于返回数据,这样用户就不能设置/更改内部值。在这种情况下,可以使用inheritance of models,类似于

class userBase(BaseModel):
    # shared fields

class UserInput(userBase):
    # fields dedicated to the input of a user

class UserOutput(userBase):
    # fields dedicated to the output of a user

相关问题