09. 开发学生登录、注册、个人信息、修改密码功能

182 字约 1 分钟读完164 次阅读更新于 2026/5/3

登录接口

# 登录
@api_router.post("/login")
async def login(account: Account):
    if account.role == '管理员':
        admin = await Admin.get_or_none(username=account.username)
        if admin is None:
            raise CustomException("账号或密码错误")
        if admin.password != account.password:
            raise CustomException("账号或密码错误")
        account = Account.model_validate(admin)
    elif account.role == '学生':
        student = await Student.get_or_none(username=account.username).prefetch_related("clazz")
        if student is None:
            raise CustomException("账号或密码错误")
        if student.password != account.password:
            raise CustomException("账号或密码错误")
        account = Account.model_validate(student)
        account.clazzId = student.clazz.id if student and student.clazz else None
    else:
        raise CustomException("角色错误")
    return Result.success(account)

注意 Account 的数据模型

class Account(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: int | None = None
    username: str | None = None
    password: str | None = None
    newPassword: str | None = None
    role: str | None = None
    name: str | None = None
    avatar: str | None = None
    clazzId: int | None = None

注册接口

# 注册
@api_router.post("/register")
async def register(account: Account):
    if account.username is None:
        raise CustomException("账号不能为空")
    if account.password is None:
        raise CustomException("密码不能为空")
    # 设置默认的name
    if account.name is None:
        account.name = account.username
    student = await Student.get_or_none(username=account.username)
    if student is not None:
        raise CustomException("账号已存在")
    create_data = account.model_dump(exclude_unset=True, exclude={"id"})
    await Student.create(**create_data)
    return Result.success()

关联查询的时候,关联的条件 必须加上 if 判断

最终学生的分页查询

# 分页查询数据
@router.get('/selectPage')
async def select_all(name: str = "", clazzName: str = "", majorName: str = "", pageNum: int = 1, pageSize: int = 10):
    # name__contains表示根据name进行模糊查询  prefetch_related 关联查询到 major模块的数据
    query = Student.filter(name__contains=name)
    if clazzName and clazzName != "":
        query = query.filter(clazz__name__contains=clazzName)
    if majorName and clazzName != "":
        query = query.filter(clazz__major__name__contains=majorName)
    query = query.prefetch_related("clazz__major")
    student_list = await query.offset((pageNum - 1) * pageSize).limit(pageSize)
    total = await query.count()
    # student_list 转成字典数据
    # majorName 怎么返回??
    # {id=xxx, name=xxx, no=xxx}
    student_dict_list = [
        {
            **StudentPydantic.model_validate(student).model_dump(),  # id=xxx,no=xxx,name=xxx
            "clazzId": student.clazz.id if student.clazz else None,
            "clazzName": student.clazz.name if student.clazz else None,
            "majorName": student.clazz.major.name if student.clazz and student.clazz.major else None
        }
        for student in student_list
    ]
    page_info = PageInfo(list=student_dict_list, total=total)
    return Result.success(page_info)

个人信息页面 Person.vue

修改密码接口

# 修改密码
@api_router.put("/updatePassword")
async def update_password(account: Account):
    if account.role == '管理员':
        admin = await Admin.get_or_none(id=account.id)
        if admin is None:
            raise CustomException("未找到用户")
        if admin.password != account.password:
            raise CustomException("原密码错误")
        if admin.password == account.newPassword:
            raise CustomException("新密码不能原密码跟相同")
        await Admin.filter(id=admin.id).update(password=account.newPassword)
    if account.role == '学生':
        student = await Student.get_or_none(id=account.id)
        if student is None:
            raise CustomException("未找到用户")
        if student.password != account.password:
            raise CustomException("原密码错误")
        if student.password == account.newPassword:
            raise CustomException("新密码不能原密码跟相同")
        await Student.filter(id=student.id).update(password=account.newPassword)
    return Result.success(account)

Password.vue