204 lines
6.4 KiB
Python

from typing import Any, List
from fastapi import APIRouter, Depends, HTTPException, Path, Response, status
from sqlalchemy.orm import Session
from app import crud, models, schemas
from app.api.v1.deps import get_db, get_current_active_user, get_admin_user
router = APIRouter()
@router.get("/", response_model=List[schemas.Teacher])
def read_teachers(
db: Session = Depends(get_db),
skip: int = 0,
limit: int = 100,
current_user: models.User = Depends(get_current_active_user),
) -> Any:
"""
Retrieve teachers.
"""
# Regular users can only see their own teacher profile if they are a teacher
if crud.user.is_admin(current_user):
teachers = db.query(models.Teacher).offset(skip).limit(limit).all()
else:
teacher = db.query(models.Teacher).filter(models.Teacher.user_id == current_user.id).first()
teachers = [teacher] if teacher else []
return teachers
@router.get("/{teacher_id}", response_model=schemas.TeacherWithUser)
def read_teacher(
*,
db: Session = Depends(get_db),
teacher_id: int = Path(..., title="The ID of the teacher to get"),
current_user: models.User = Depends(get_current_active_user),
) -> Any:
"""
Get teacher by ID.
"""
teacher = db.query(models.Teacher).filter(models.Teacher.id == teacher_id).first()
if not teacher:
raise HTTPException(
status_code=404,
detail="Teacher not found",
)
# Regular users can only see their own teacher profile
if not crud.user.is_admin(current_user) and teacher.user_id != current_user.id:
raise HTTPException(
status_code=403,
detail="Not enough permissions to view this teacher profile"
)
# Get user details
user = crud.user.get(db=db, id=teacher.user_id)
# Create a combined response
result = schemas.TeacherWithUser.from_orm(teacher)
result.user = user
return result
@router.post("/", response_model=schemas.Teacher)
def create_teacher(
*,
db: Session = Depends(get_db),
teacher_in: schemas.teacher.TeacherCreate,
current_user: models.User = Depends(get_admin_user),
) -> Any:
"""
Create new teacher.
"""
# Check if the user exists
user = crud.user.get(db=db, id=teacher_in.user_id)
if not user:
raise HTTPException(
status_code=404,
detail=f"User with ID {teacher_in.user_id} not found",
)
# Check if teacher profile already exists for this user
existing_teacher = db.query(models.Teacher).filter(models.Teacher.user_id == user.id).first()
if existing_teacher:
raise HTTPException(
status_code=400,
detail=f"Teacher profile already exists for user ID {user.id}",
)
# Check if teacher_id is unique
existing_teacher_id = db.query(models.Teacher).filter(models.Teacher.teacher_id == teacher_in.teacher_id).first()
if existing_teacher_id:
raise HTTPException(
status_code=400,
detail=f"Teacher ID {teacher_in.teacher_id} is already taken",
)
# Create teacher profile
db_teacher = models.Teacher(
teacher_id=teacher_in.teacher_id,
date_of_birth=teacher_in.date_of_birth,
address=teacher_in.address,
phone_number=teacher_in.phone_number,
department=teacher_in.department,
hire_date=teacher_in.hire_date,
user_id=teacher_in.user_id,
)
db.add(db_teacher)
db.commit()
db.refresh(db_teacher)
return db_teacher
@router.put("/{teacher_id}", response_model=schemas.Teacher)
def update_teacher(
*,
db: Session = Depends(get_db),
teacher_id: int = Path(..., title="The ID of the teacher to update"),
teacher_in: schemas.teacher.TeacherUpdate,
current_user: models.User = Depends(get_current_active_user),
) -> Any:
"""
Update a teacher.
"""
teacher = db.query(models.Teacher).filter(models.Teacher.id == teacher_id).first()
if not teacher:
raise HTTPException(
status_code=404,
detail="Teacher not found",
)
# Regular users can only update their own teacher profile
if not crud.user.is_admin(current_user) and teacher.user_id != current_user.id:
raise HTTPException(
status_code=403,
detail="Not enough permissions to update this teacher profile"
)
# Check if teacher_id is unique if it's being updated
if teacher_in.teacher_id and teacher_in.teacher_id != teacher.teacher_id:
existing_teacher_id = db.query(models.Teacher).filter(models.Teacher.teacher_id == teacher_in.teacher_id).first()
if existing_teacher_id:
raise HTTPException(
status_code=400,
detail=f"Teacher ID {teacher_in.teacher_id} is already taken",
)
# Update teacher fields
update_data = teacher_in.dict(exclude_unset=True)
for field, value in update_data.items():
setattr(teacher, field, value)
db.add(teacher)
db.commit()
db.refresh(teacher)
return teacher
@router.delete("/{teacher_id}", response_model=None, status_code=status.HTTP_204_NO_CONTENT)
def delete_teacher(
*,
db: Session = Depends(get_db),
teacher_id: int = Path(..., title="The ID of the teacher to delete"),
current_user: models.User = Depends(get_admin_user),
) -> Any:
"""
Delete a teacher.
"""
teacher = db.query(models.Teacher).filter(models.Teacher.id == teacher_id).first()
if not teacher:
raise HTTPException(
status_code=404,
detail="Teacher not found",
)
db.delete(teacher)
db.commit()
return Response(status_code=status.HTTP_204_NO_CONTENT)
@router.get("/{teacher_id}/courses", response_model=List[schemas.Course])
def read_teacher_courses(
*,
db: Session = Depends(get_db),
teacher_id: int = Path(..., title="The ID of the teacher to get courses for"),
current_user: models.User = Depends(get_current_active_user),
) -> Any:
"""
Get all courses taught by a teacher.
"""
teacher = db.query(models.Teacher).filter(models.Teacher.id == teacher_id).first()
if not teacher:
raise HTTPException(
status_code=404,
detail="Teacher not found",
)
courses = db.query(models.Course).filter(models.Course.teacher_id == teacher_id).all()
return courses