added organ api

This commit is contained in:
Philip Cheung 2024-10-26 19:45:53 +08:00
parent ee26660d3a
commit dcf4e3efe8
4 changed files with 245 additions and 43 deletions

View File

@ -0,0 +1,36 @@
"""add organ
Revision ID: e77992962f85
Revises: 7acc8c28d84c
Create Date: 2024-10-26 19:33:40.557599
"""
from alembic import op
import sqlalchemy as sa
import sqlmodel.sql.sqltypes
# revision identifiers, used by Alembic.
revision = 'e77992962f85'
down_revision = '7acc8c28d84c'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('organ',
sa.Column('description', sqlmodel.sql.sqltypes.AutoString(length=1024), nullable=False),
sa.Column('image', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=True),
sa.Column('title', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False),
sa.Column('index', sa.Integer(), nullable=False),
sa.Column('id', sa.Uuid(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('organ')
# ### end Alembic commands ###

View File

@ -1,6 +1,6 @@
from fastapi import APIRouter from fastapi import APIRouter
from app.api.routes import items, login, users, utils, messages, setting, aboutUs, course, image, info_image, sechedule from app.api.routes import items, login, users, utils, messages, setting, aboutUs, course, image, info_image, sechedule, organ
api_router = APIRouter() api_router = APIRouter()
api_router.include_router(login.router, tags=["login"]) api_router.include_router(login.router, tags=["login"])
@ -10,6 +10,7 @@ api_router.include_router(items.router, prefix="/items", tags=["items"])
api_router.include_router(messages.router, prefix="/messages", tags=["messages"]) api_router.include_router(messages.router, prefix="/messages", tags=["messages"])
api_router.include_router(setting.router, prefix="/setting", tags=["setting"]) api_router.include_router(setting.router, prefix="/setting", tags=["setting"])
api_router.include_router(aboutUs.router, prefix="/aboutUs", tags=["aboutUs"]) api_router.include_router(aboutUs.router, prefix="/aboutUs", tags=["aboutUs"])
api_router.include_router(organ.router, prefix="/organ", tags=["organ"])
api_router.include_router(course.router, prefix="/course", tags=["course"]) api_router.include_router(course.router, prefix="/course", tags=["course"])
api_router.include_router(image.router, prefix="/image", tags=["image"]) api_router.include_router(image.router, prefix="/image", tags=["image"])
api_router.include_router(info_image.router, prefix="/info_image", tags=["info_image"]) api_router.include_router(info_image.router, prefix="/info_image", tags=["info_image"])

View File

@ -0,0 +1,98 @@
import uuid
from typing import Any, Annotated, Optional
from app.utils import validate_file_size_type, save_picture, del_picture
from fastapi import APIRouter, HTTPException, UploadFile, File, Form
from sqlmodel import func, select
from app.api.deps import CurrentUser, SessionDep
from app.models import (
Organ,
OrganPublic,
OrganCreate,
OrganUpdate,
OrganListPublic,
Message
)
router = APIRouter()
@router.post("/", response_model=OrganPublic)
async def create_organ(
*,
session: SessionDep,
current_user: CurrentUser,
description: str = Form(),
title: str = Form(),
image: Annotated[UploadFile, File()],
index: int = Form()
) -> Any:
"""
Create new about us.
"""
validate_file_size_type(image)
imageUrl = await save_picture(file=image, folder_name="tmp")
# aboutus_in.image = imageUrl
organ_in = OrganCreate(description=description, image=imageUrl, index=index ,title=title)
organ = Organ.from_orm(organ_in)
session.add(organ)
session.commit()
session.refresh(organ)
return organ
@router.put("/{id}", response_model= OrganPublic)
async def edit_organ(
*,
session: SessionDep,
current_user: CurrentUser,
id: uuid.UUID,
description: str = Form(),
image: Annotated[UploadFile, File()] = None,
title: str = Form(),
index: int = Form()
) -> Any:
organ = session.get(Organ, id)
if image is not None:
validate_file_size_type(image)
imageUrl = await save_picture(file=image, folder_name="tmp")
await del_picture(organ.image)
organ_in = OrganUpdate(description=description, image=imageUrl, index=index, title=title)
else :
organ_in = OrganUpdate(description=description, image=organ.image, index=index, title=title)
update_dict = organ_in.model_dump(exclude_unset=True)
organ.sqlmodel_update(update_dict)
session.add(organ)
session.commit()
session.refresh(organ)
return organ
@router.get("/", response_model=OrganListPublic)
def read_organ_list(session: SessionDep, skip: int = 0, limit: int = 100) -> Any:
count_statement = select(func.count()).select_from(Organ)
count = session.exec(count_statement).one()
statement = select(Organ).offset(skip).limit(limit)
organ = session.exec(statement).all()
return OrganListPublic(data=organ, count=count)
@router.delete("/{id}")
async def delete_organ(
session: SessionDep, current_user: CurrentUser, id: uuid.UUID
) -> Message:
"""
Delete an course.
"""
organ = session.get(Organ, id)
if not organ:
raise HTTPException(status_code=404, detail="aboutUs not found")
await del_picture(organ.image)
session.delete(organ)
session.commit()
return Message(message="aboutUs deleted successfully")

View File

@ -4,6 +4,8 @@ from pydantic import EmailStr, BaseModel
from sqlmodel import Field, Relationship, SQLModel from sqlmodel import Field, Relationship, SQLModel
from datetime import datetime from datetime import datetime
from sqlalchemy import JSON from sqlalchemy import JSON
# Shared properties # Shared properties
class UserBase(SQLModel): class UserBase(SQLModel):
email: EmailStr = Field(unique=True, index=True, max_length=255) email: EmailStr = Field(unique=True, index=True, max_length=255)
@ -116,19 +118,23 @@ class NewPassword(SQLModel):
# Client Messages # Client Messages
class MessageBase(SQLModel): class MessageBase(SQLModel):
name: str = Field(max_length=255) name: str = Field(max_length=255)
phone: str = Field(max_length=255) phone: str = Field(max_length=255)
email: str = Field(max_length=255) email: str = Field(max_length=255)
message: str = Field(max_length=1024) message: str = Field(max_length=1024)
class Message(MessageBase, table=True): class Message(MessageBase, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
created_at: datetime = Field(default_factory=datetime.utcnow) created_at: datetime = Field(default_factory=datetime.utcnow)
class MessageCreate(MessageBase): class MessageCreate(MessageBase):
pass pass
class MessagePublic(MessageBase): class MessagePublic(MessageBase):
id: uuid.UUID id: uuid.UUID
@ -137,8 +143,8 @@ class MessagesPublic(SQLModel):
data: list[Message] data: list[Message]
count: int count: int
# setting
# setting
class SettingBase(SQLModel): class SettingBase(SQLModel):
@ -154,37 +160,78 @@ class SettingBase(SQLModel):
youtube_link: str = Field(max_length=255) youtube_link: str = Field(max_length=255)
whatsapp: str = Field(max_length=255) whatsapp: str = Field(max_length=255)
class SettingCreate(SettingBase): class SettingCreate(SettingBase):
pass pass
class Setting(SettingBase, table=True): class Setting(SettingBase, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
# organ
class OrganBase(SQLModel):
description: str = Field(max_length=1024)
image: str | None = Field(default=None, max_length=255)
title: str = Field(max_length=255)
index: int
class OrganCreate(OrganBase):
pass
class Organ(OrganBase, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
class OrganPublic(OrganBase):
id: uuid.UUID
class OrganUpdate(OrganBase):
pass
class OrganListPublic(SQLModel):
data: list[OrganPublic]
count: int
# About us # About us
class AboutUsBase(SQLModel): class AboutUsBase(SQLModel):
description: str = Field(max_length=1024) description: str = Field(max_length=1024)
image: str | None = Field(default=None, max_length=255) image: str | None = Field(default=None, max_length=255)
title: str = Field(max_length=255) title: str = Field(max_length=255)
index: int index: int
class AboutUsCreate(AboutUsBase): class AboutUsCreate(AboutUsBase):
pass pass
class AboutUs(AboutUsBase, table=True): class AboutUs(AboutUsBase, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
class AboutUsPublic(AboutUsBase): class AboutUsPublic(AboutUsBase):
id: uuid.UUID id: uuid.UUID
class AboutsUpdate(AboutUsBase): class AboutsUpdate(AboutUsBase):
pass pass
class AboutsListPublic(SQLModel): class AboutsListPublic(SQLModel):
data: list[AboutUsPublic] data: list[AboutUsPublic]
count: int count: int
# courses # courses
class CourseBase(SQLModel): class CourseBase(SQLModel):
title: str = Field(max_length=255) title: str = Field(max_length=255)
sort_description: str = Field(max_length=32768) sort_description: str = Field(max_length=32768)
@ -193,18 +240,26 @@ class CourseBase(SQLModel):
contant: str = Field(max_length=32768) contant: str = Field(max_length=32768)
remark: str = Field(max_length=32768) remark: str = Field(max_length=32768)
class CourseCreate(CourseBase): class CourseCreate(CourseBase):
pass pass
class CourseUpdate(CourseBase): class CourseUpdate(CourseBase):
pass pass
class Course(CourseBase, table=True): class Course(CourseBase, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
created_at: datetime = Field(default_factory=datetime.utcnow) created_at: datetime = Field(default_factory=datetime.utcnow)
images: list["Image"] = Relationship(back_populates="course", cascade_delete=True) images: list["Image"] = Relationship(back_populates="course", cascade_delete=True)
info_images: list["Info_Image"] = Relationship(back_populates="course", cascade_delete=True) info_images: list["Info_Image"] = Relationship(
schedule: list["Schedule"] = Relationship(back_populates="course", cascade_delete=True) back_populates="course", cascade_delete=True
)
schedule: list["Schedule"] = Relationship(
back_populates="course", cascade_delete=True
)
class CoursePublic(CourseBase): class CoursePublic(CourseBase):
id: uuid.UUID id: uuid.UUID
@ -214,6 +269,7 @@ class CoursePublic(CourseBase):
schedule: list["Schedule"] schedule: list["Schedule"]
created_at: datetime created_at: datetime
class CoursesPublic(SQLModel): class CoursesPublic(SQLModel):
data: list[CoursePublic] data: list[CoursePublic]
count: int count: int
@ -228,27 +284,36 @@ class ImageBase(SQLModel):
class ImagePublic(ImageBase): class ImagePublic(ImageBase):
id: uuid.UUID id: uuid.UUID
class ImageCreate(ImageBase): class ImageCreate(ImageBase):
course_id: uuid.UUID course_id: uuid.UUID
class Image(ImageBase, table=True): class Image(ImageBase, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
course_id: uuid.UUID = Field(foreign_key="course.id", nullable=False, ondelete="CASCADE") course_id: uuid.UUID = Field(
foreign_key="course.id", nullable=False, ondelete="CASCADE"
)
course: Course | None = Relationship(back_populates="images") course: Course | None = Relationship(back_populates="images")
class Info_ImageBase(SQLModel): class Info_ImageBase(SQLModel):
image: str = Field(max_length=255) image: str = Field(max_length=255)
index: int index: int
class Info_ImageCreate(Info_ImageBase): class Info_ImageCreate(Info_ImageBase):
course_id: uuid.UUID course_id: uuid.UUID
class Info_Image(Info_ImageBase, table=True): class Info_Image(Info_ImageBase, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
course_id: uuid.UUID = Field(foreign_key="course.id", nullable=False, ondelete="CASCADE") course_id: uuid.UUID = Field(
foreign_key="course.id", nullable=False, ondelete="CASCADE"
)
course: Course | None = Relationship(back_populates="info_images") course: Course | None = Relationship(back_populates="info_images")
# schedules # schedules
class ScheduleBase(SQLModel): class ScheduleBase(SQLModel):
title: str = Field(max_length=255) title: str = Field(max_length=255)
@ -256,15 +321,20 @@ class ScheduleBase(SQLModel):
info2: str = Field(max_length=255) info2: str = Field(max_length=255)
date: str date: str
class ScheduleUpdate(ScheduleBase): class ScheduleUpdate(ScheduleBase):
pass pass
class ScheduleCreate(ScheduleBase): class ScheduleCreate(ScheduleBase):
course_id: uuid.UUID course_id: uuid.UUID
class Schedule(ScheduleBase, table=True): class Schedule(ScheduleBase, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
course_id: uuid.UUID = Field(foreign_key="course.id", nullable=False, ondelete="CASCADE") course_id: uuid.UUID = Field(
foreign_key="course.id", nullable=False, ondelete="CASCADE"
)
course: Course | None = Relationship(back_populates="schedule") course: Course | None = Relationship(back_populates="schedule")
@ -272,6 +342,3 @@ class CoursePublicWithImages(CoursePublic):
images: list[Image] = [] images: list[Image] = []
info_images: list[Info_Image] = [] info_images: list[Info_Image] = []
schedule: list[Schedule] = [] schedule: list[Schedule] = []