mirror of
https://github.com/wowlikon/LiB.git
synced 2026-03-21 23:53:38 +00:00
исправление обработки 404
This commit is contained in:
@@ -287,7 +287,8 @@ def enable_2fa(
|
||||
|
||||
if not current_user.totp_secret:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST, detail="Secret key not generated"
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Secret key not generated",
|
||||
)
|
||||
|
||||
if not verify_totp_code(secret, data.code):
|
||||
@@ -299,7 +300,8 @@ def enable_2fa(
|
||||
decrypted = cipher.decrypt(base64.b64decode(current_user.totp_secret.encode()))
|
||||
if secret != decrypted.decode():
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST, detail="Incorret secret"
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Incorret secret",
|
||||
)
|
||||
|
||||
current_user.is_2fa_enabled = True
|
||||
|
||||
@@ -67,7 +67,8 @@ def get_author(
|
||||
author = session.get(Author, author_id)
|
||||
if not author:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Author not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Author not found",
|
||||
)
|
||||
|
||||
books = session.exec(
|
||||
@@ -98,7 +99,8 @@ def update_author(
|
||||
db_author = session.get(Author, author_id)
|
||||
if not db_author:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Author not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Author not found",
|
||||
)
|
||||
|
||||
update_data = author.model_dump(exclude_unset=True)
|
||||
@@ -125,7 +127,8 @@ def delete_author(
|
||||
author = session.get(Author, author_id)
|
||||
if not author:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Author not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Author not found",
|
||||
)
|
||||
|
||||
author_read = AuthorRead(**author.model_dump())
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
"""Модуль работы с книгами"""
|
||||
from library_service.services import transcode_image
|
||||
import shutil
|
||||
from uuid import uuid4
|
||||
|
||||
from pydantic import Field
|
||||
from typing_extensions import Annotated
|
||||
|
||||
from sqlalchemy.orm import selectinload, defer
|
||||
|
||||
from sqlalchemy import text, case, distinct
|
||||
from uuid import uuid4
|
||||
import shutil
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from typing import List
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Path, Query, status, UploadFile, File
|
||||
from ollama import Client
|
||||
from pydantic import Field
|
||||
from sqlalchemy import text, case, distinct
|
||||
from sqlalchemy.orm import selectinload, defer
|
||||
from sqlmodel import Session, select, col, func
|
||||
|
||||
from library_service.auth import RequireStaff
|
||||
from library_service.services import transcode_image
|
||||
from library_service.settings import get_session, OLLAMA_URL, BOOKS_PREVIEW_DIR
|
||||
from library_service.models.enums import BookStatus
|
||||
from library_service.models.db import (
|
||||
@@ -139,7 +136,8 @@ def create_book(
|
||||
session.commit()
|
||||
session.refresh(db_book)
|
||||
|
||||
book_data = db_book.model_dump(exclude={"embedding", "preview_id"})
|
||||
book_dict = {k: v for k, v in db_book.__dict__.items() if not k.startswith('_')}
|
||||
book_data = {k: v for k, v in book_dict.items() if k not in {"embedding", "preview_id"}}
|
||||
book_data["preview_urls"] = {
|
||||
"png": f"/static/books/{db_book.preview_id}.png",
|
||||
"jpeg": f"/static/books/{db_book.preview_id}.jpg",
|
||||
@@ -160,12 +158,17 @@ def read_books(session: Session = Depends(get_session)):
|
||||
|
||||
books_data = []
|
||||
for book in books:
|
||||
book_data = book.model_dump(exclude={"embedding", "preview_id"})
|
||||
book = book[0]
|
||||
book_dict = dict(book)
|
||||
|
||||
book_data = {k: v for k, v in book_dict.items() if k not in {"embedding", "preview_id"}}
|
||||
|
||||
book_data["preview_urls"] = {
|
||||
"png": f"/static/books/{book.preview_id}.png",
|
||||
"jpeg": f"/static/books/{book.preview_id}.jpg",
|
||||
"webp": f"/static/books/{book.preview_id}.webp",
|
||||
} if book.preview_id else {}
|
||||
|
||||
books_data.append(book_data)
|
||||
|
||||
return BookList(
|
||||
@@ -188,7 +191,8 @@ def get_book(
|
||||
book = session.get(Book, book_id)
|
||||
if not book:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Book not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Book not found",
|
||||
)
|
||||
|
||||
authors = session.scalars(
|
||||
@@ -203,7 +207,8 @@ def get_book(
|
||||
|
||||
genre_reads = [GenreRead(**genre.model_dump()) for genre in genres]
|
||||
|
||||
book_data = book.model_dump(exclude={"embedding", "preview_id"})
|
||||
book_dict = {k: v for k, v in book.__dict__.items() if not k.startswith('_')}
|
||||
book_data = {k: v for k, v in book_dict.items() if k not in {"embedding", "preview_id"}}
|
||||
book_data["preview_urls"] = {
|
||||
"png": f"/static/books/{book.preview_id}.png",
|
||||
"jpeg": f"/static/books/{book.preview_id}.jpg",
|
||||
@@ -231,7 +236,8 @@ def update_book(
|
||||
db_book = session.get(Book, book_id)
|
||||
if not db_book:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Book not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Book not found",
|
||||
)
|
||||
|
||||
if book_update.status is not None:
|
||||
@@ -292,7 +298,8 @@ def delete_book(
|
||||
book = session.get(Book, book_id)
|
||||
if not book:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Book not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Book not found",
|
||||
)
|
||||
book_read = BookRead(
|
||||
id=(book.id or 0),
|
||||
@@ -313,10 +320,16 @@ async def upload_book_preview(
|
||||
session: Session = Depends(get_session)
|
||||
):
|
||||
if not (file.content_type or "").startswith("image/"):
|
||||
raise HTTPException(status.HTTP_415_UNSUPPORTED_MEDIA_TYPE, "Image required")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,
|
||||
detail="Image required",
|
||||
)
|
||||
|
||||
if (file.size or 0) > 32 * 1024 * 1024:
|
||||
raise HTTPException(status.HTTP_413_REQUEST_ENTITY_TOO_LARGE, "File larger than 10 MB")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
|
||||
detail="File larger than 10 MB",
|
||||
)
|
||||
|
||||
file_uuid= uuid4()
|
||||
tmp_path = BOOKS_PREVIEW_DIR / f"{file_uuid}.upload"
|
||||
@@ -327,7 +340,10 @@ async def upload_book_preview(
|
||||
book = session.get(Book, book_id)
|
||||
if not book:
|
||||
tmp_path.unlink()
|
||||
raise HTTPException(status.HTTP_404_NOT_FOUND, "Book not found")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Book not found",
|
||||
)
|
||||
|
||||
transcode_image(tmp_path)
|
||||
tmp_path.unlink()
|
||||
|
||||
@@ -27,11 +27,13 @@ async def challenge(request: Request, ip: str = Depends(get_ip)):
|
||||
"""Возвращает задачу capjs"""
|
||||
if challenges_by_ip[ip] >= MAX_CHALLENGES_PER_IP:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_429_TOO_MANY_REQUESTS, detail="Too many challenges"
|
||||
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
|
||||
detail="Too many challenges",
|
||||
)
|
||||
if len(active_challenges) >= MAX_TOTAL_CHALLENGES:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Server busy"
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Server busy",
|
||||
)
|
||||
|
||||
token = secrets.token_hex(25)
|
||||
@@ -60,17 +62,22 @@ async def redeem(request: Request, payload: dict, ip: str = Depends(get_ip)):
|
||||
|
||||
if token not in active_challenges:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Invalid challenge"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Invalid challenge",
|
||||
)
|
||||
|
||||
ch = active_challenges.pop(token)
|
||||
challenges_by_ip[ch["ip"]] -= 1
|
||||
|
||||
if now_ms() > ch["expires"]:
|
||||
raise HTTPException(status_code=status.HTTP_410_GONE, detail="Expired")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_410_GONE,
|
||||
detail="Expired"
|
||||
)
|
||||
if len(solutions) < ch["c"]:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST, detail="Bad solutions"
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Bad solutions",
|
||||
)
|
||||
|
||||
def verify(i: int) -> bool:
|
||||
@@ -84,7 +91,8 @@ async def redeem(request: Request, payload: dict, ip: str = Depends(get_ip)):
|
||||
)
|
||||
if not all(results):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid solution"
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Invalid solution",
|
||||
)
|
||||
|
||||
r_token = ch["redeem_token"]
|
||||
|
||||
@@ -66,7 +66,8 @@ def get_genre(
|
||||
genre = session.get(Genre, genre_id)
|
||||
if not genre:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Genre not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Genre not found",
|
||||
)
|
||||
|
||||
books = session.exec(
|
||||
@@ -97,7 +98,8 @@ def update_genre(
|
||||
db_genre = session.get(Genre, genre_id)
|
||||
if not db_genre:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Genre not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Genre not found",
|
||||
)
|
||||
|
||||
update_data = genre.model_dump(exclude_unset=True)
|
||||
@@ -124,7 +126,8 @@ def delete_genre(
|
||||
genre = session.get(Genre, genre_id)
|
||||
if not genre:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Genre not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Genre not found",
|
||||
)
|
||||
|
||||
genre_read = GenreRead(**genre.model_dump())
|
||||
|
||||
@@ -41,7 +41,8 @@ def create_loan(
|
||||
book = session.get(Book, loan.book_id)
|
||||
if not book:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Book not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Book not found",
|
||||
)
|
||||
|
||||
if book.status != BookStatus.ACTIVE:
|
||||
@@ -53,7 +54,8 @@ def create_loan(
|
||||
target_user = session.get(User, loan.user_id)
|
||||
if not target_user:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="User not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="User not found",
|
||||
)
|
||||
|
||||
db_loan = BookUserLink(
|
||||
@@ -253,14 +255,16 @@ def get_loan(
|
||||
|
||||
if not loan:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Loan not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Loan not found",
|
||||
)
|
||||
|
||||
is_staff = is_user_staff(current_user)
|
||||
|
||||
if not is_staff and loan.user_id != current_user.id:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN, detail="Access denied to this loan"
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Access denied to this loan",
|
||||
)
|
||||
|
||||
return LoanRead(**loan.model_dump())
|
||||
@@ -282,7 +286,8 @@ def update_loan(
|
||||
db_loan = session.get(BookUserLink, loan_id)
|
||||
if not db_loan:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Loan not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Loan not found",
|
||||
)
|
||||
|
||||
is_staff = is_user_staff(current_user)
|
||||
@@ -296,7 +301,8 @@ def update_loan(
|
||||
book = session.get(Book, db_loan.book_id)
|
||||
if not book:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Book not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Book not found",
|
||||
)
|
||||
|
||||
if loan_update.user_id is not None:
|
||||
@@ -308,7 +314,8 @@ def update_loan(
|
||||
new_user = session.get(User, loan_update.user_id)
|
||||
if not new_user:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="User not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="User not found",
|
||||
)
|
||||
db_loan.user_id = loan_update.user_id
|
||||
|
||||
@@ -347,18 +354,21 @@ def confirm_loan(
|
||||
loan = session.get(BookUserLink, loan_id)
|
||||
if not loan:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Loan not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Loan not found",
|
||||
)
|
||||
|
||||
if loan.returned_at:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST, detail="Loan is already returned"
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Loan is already returned",
|
||||
)
|
||||
|
||||
book = session.get(Book, loan.book_id)
|
||||
if not book:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Book not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Book not found",
|
||||
)
|
||||
|
||||
if book.status not in [BookStatus.RESERVED, BookStatus.ACTIVE]:
|
||||
@@ -392,12 +402,14 @@ def return_loan(
|
||||
loan = session.get(BookUserLink, loan_id)
|
||||
if not loan:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Loan not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Loan not found",
|
||||
)
|
||||
|
||||
if loan.returned_at:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST, detail="Loan is already returned"
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Loan is already returned",
|
||||
)
|
||||
|
||||
loan.returned_at = datetime.now(timezone.utc)
|
||||
@@ -429,7 +441,8 @@ def delete_loan(
|
||||
loan = session.get(BookUserLink, loan_id)
|
||||
if not loan:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Loan not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Loan not found",
|
||||
)
|
||||
|
||||
is_staff = is_user_staff(current_user)
|
||||
@@ -499,7 +512,8 @@ def issue_book_directly(
|
||||
book = session.get(Book, loan.book_id)
|
||||
if not book:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Book not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Book not found",
|
||||
)
|
||||
|
||||
if book.status != BookStatus.ACTIVE:
|
||||
@@ -511,7 +525,8 @@ def issue_book_directly(
|
||||
target_user = session.get(User, loan.user_id)
|
||||
if not target_user:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="User not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="User not found",
|
||||
)
|
||||
|
||||
db_loan = BookUserLink(
|
||||
|
||||
@@ -56,8 +56,14 @@ async def create_genre(request: Request, app=Depends(lambda: get_app())):
|
||||
|
||||
|
||||
@router.get("/genre/{genre_id}/edit", include_in_schema=False)
|
||||
async def edit_genre(request: Request, genre_id: int, app=Depends(lambda: get_app())):
|
||||
async def edit_genre(request: Request, genre_id: str, app=Depends(lambda: get_app())):
|
||||
"""Рендерит страницу редактирования жанра"""
|
||||
|
||||
try:
|
||||
assert int(genre_id) > 0
|
||||
except:
|
||||
return await unknown(request, app)
|
||||
|
||||
return templates.TemplateResponse(request, "edit_genre.html", get_info(app) | {"request": request, "title": "LiB - Редактировать жанр", "id": genre_id})
|
||||
|
||||
|
||||
@@ -74,15 +80,32 @@ async def create_author(request: Request, app=Depends(lambda: get_app())):
|
||||
|
||||
|
||||
@router.get("/author/{author_id}/edit", include_in_schema=False)
|
||||
async def edit_author(request: Request, author_id: int, app=Depends(lambda: get_app())):
|
||||
async def edit_author(request: Request, author_id: str, app=Depends(lambda: get_app()), session=Depends(get_session)):
|
||||
"""Рендерит страницу редактирования автора"""
|
||||
return templates.TemplateResponse(request, "edit_author.html", get_info(app) | {"request": request, "title": "LiB - Редактировать автора", "id": author_id})
|
||||
|
||||
try:
|
||||
author = session.get(Author, int(author_id))
|
||||
assert author is not None
|
||||
except:
|
||||
return await unknown(request, app)
|
||||
|
||||
return templates.TemplateResponse(request, "edit_author.html", get_info(app) | {"request": request, "title": f"LiB - Редактировать автора \"{author.name}\"", "id": author_id})
|
||||
|
||||
|
||||
@router.get("/author/{author_id}", include_in_schema=False)
|
||||
async def author(request: Request, author_id: int, app=Depends(lambda: get_app())):
|
||||
async def author(request: Request, author_id: str, app=Depends(lambda: get_app()), session=Depends(get_session)):
|
||||
"""Рендерит страницу просмотра автора"""
|
||||
return templates.TemplateResponse(request, "author.html", get_info(app) | {"request": request, "title": "LiB - Автор", "id": author_id})
|
||||
|
||||
if author_id == "":
|
||||
return RedirectResponse("/authors")
|
||||
|
||||
try:
|
||||
author = session.get(Author, int(author_id))
|
||||
assert author is not None
|
||||
except:
|
||||
return await unknown(request, app)
|
||||
|
||||
return templates.TemplateResponse(request, "author.html", get_info(app) | {"request": request, "title": f"LiB - Автор \"{author.name}\"", "id": author_id})
|
||||
|
||||
|
||||
@router.get("/books", include_in_schema=False)
|
||||
@@ -98,16 +121,32 @@ async def create_book(request: Request, app=Depends(lambda: get_app())):
|
||||
|
||||
|
||||
@router.get("/book/{book_id}/edit", include_in_schema=False)
|
||||
async def edit_book(request: Request, book_id: int, app=Depends(lambda: get_app())):
|
||||
async def edit_book(request: Request, book_id: str, app=Depends(lambda: get_app()), session=Depends(get_session)):
|
||||
"""Рендерит страницу редактирования книги"""
|
||||
return templates.TemplateResponse(request, "edit_book.html", get_info(app) | {"request": request, "title": "LiB - Редактировать книгу", "id": book_id})
|
||||
|
||||
try:
|
||||
book = session.get(Book, int(book_id))
|
||||
assert book is not None
|
||||
except:
|
||||
return await unknown(request, app)
|
||||
|
||||
return templates.TemplateResponse(request, "edit_book.html", get_info(app) | {"request": request, "title": f"LiB - Редактировать книгу \"{book.title}\"", "id": book_id})
|
||||
|
||||
|
||||
@router.get("/book/{book_id}", include_in_schema=False)
|
||||
async def book(request: Request, book_id: int, app=Depends(lambda: get_app()), session=Depends(get_session)):
|
||||
async def book(request: Request, book_id: str, app=Depends(lambda: get_app()), session=Depends(get_session)):
|
||||
"""Рендерит страницу просмотра книги"""
|
||||
book = session.get(Book, book_id)
|
||||
return templates.TemplateResponse(request, "book.html", get_info(app) | {"request": request, "title": "LiB - Книга", "id": book_id, "img": book.preview_id})
|
||||
|
||||
if book_id == "":
|
||||
return RedirectResponse("/books")
|
||||
|
||||
try:
|
||||
book = session.get(Book, int(book_id))
|
||||
assert book is not None
|
||||
except:
|
||||
return await unknown(request, app)
|
||||
|
||||
return templates.TemplateResponse(request, "book.html", get_info(app) | {"request": request, "title": f"LiB - Книга \"{book.title}\"", "id": book_id, "img": book.preview_id})
|
||||
|
||||
|
||||
@router.get("/auth", include_in_schema=False)
|
||||
|
||||
@@ -19,7 +19,8 @@ def check_entity_exists(session, model, entity_id, entity_name):
|
||||
entity = session.get(model, entity_id)
|
||||
if not entity:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail=f"{entity_name} not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"{entity_name} not found",
|
||||
)
|
||||
return entity
|
||||
|
||||
@@ -33,7 +34,10 @@ def add_relationship(session, link_model, id1, field1, id2, field2, detail):
|
||||
).first()
|
||||
|
||||
if existing_link:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=detail)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=detail,
|
||||
)
|
||||
|
||||
link = link_model(**{field1: id1, field2: id2})
|
||||
session.add(link)
|
||||
@@ -52,7 +56,8 @@ def remove_relationship(session, link_model, id1, field1, id2, field2):
|
||||
|
||||
if not link:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Relationship not found"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Relationship not found",
|
||||
)
|
||||
|
||||
session.delete(link)
|
||||
|
||||
Reference in New Issue
Block a user