添加上传图片
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import random
|
||||
from typing import List
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
from ninja.errors import HttpError
|
||||
from ninja import NinjaAPI
|
||||
from functools import wraps
|
||||
from typing import Callable, List, Any
|
||||
from django.http import HttpRequest
|
||||
from django.contrib.auth.decorators import login_required, user_passes_test
|
||||
from .models import User, RoleChoices
|
||||
|
||||
api = NinjaAPI()
|
||||
|
||||
|
||||
def _require(roles):
|
||||
def decorator(func):
|
||||
def _require(roles: List[RoleChoices]) -> Callable:
|
||||
def check_role(user: User) -> bool:
|
||||
return user.is_authenticated and hasattr(user, "role") and user.role in roles
|
||||
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(request, *args, **kwargs):
|
||||
if not request.user.is_authenticated:
|
||||
raise HttpError(401, "用户未登录")
|
||||
try:
|
||||
if request.user.role not in roles:
|
||||
raise HttpError(403, "你没有权限")
|
||||
except User.DoesNotExist:
|
||||
raise HttpError(404, "用户不存在")
|
||||
@login_required
|
||||
@user_passes_test(check_role, login_url=None)
|
||||
def wrapper(request: HttpRequest, *args: Any, **kwargs: Any) -> Any:
|
||||
return func(request, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
admin_required = _require([RoleChoices.ADMIN, RoleChoices.SUPER])
|
||||
|
||||
admin_required = _require([RoleChoices.ADMIN, RoleChoices.SUPER])
|
||||
super_required = _require([RoleChoices.SUPER])
|
||||
|
||||
@@ -183,3 +183,7 @@ CORS_ALLOW_CREDENTIALS = True
|
||||
NINJA_PAGINATION_CLASS = "ninja.pagination.PageNumberPagination"
|
||||
|
||||
NINJA_PAGINATION_PER_PAGE = 10
|
||||
|
||||
# Media files
|
||||
MEDIA_URL = "/media/"
|
||||
MEDIA_ROOT = BASE_DIR.parent / "media"
|
||||
|
||||
@@ -17,6 +17,8 @@ Including another URLconf
|
||||
|
||||
from django.contrib import admin
|
||||
from django.urls import path
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
from ninja import NinjaAPI
|
||||
|
||||
api = NinjaAPI()
|
||||
@@ -24,8 +26,12 @@ api = NinjaAPI()
|
||||
api.add_router("account/", "account.api.router")
|
||||
api.add_router("tutorial/", "task.tutorial.router")
|
||||
api.add_router("submission/", "submission.api.router")
|
||||
api.add_router("upload/", "utils.upload.router")
|
||||
|
||||
urlpatterns = [
|
||||
|
||||
apis = [
|
||||
path("admin/", admin.site.urls),
|
||||
path("api/", api.urls),
|
||||
]
|
||||
|
||||
urlpatterns = apis + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
||||
Submodule data/hitokoto deleted from b503a98f23
0
utils/__init__.py
Normal file
0
utils/__init__.py
Normal file
29
utils/upload.py
Normal file
29
utils/upload.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from ninja import Router, File
|
||||
from ninja.files import UploadedFile
|
||||
from pathlib import Path
|
||||
from django.conf import settings
|
||||
import uuid
|
||||
from account.decorators import super_required
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
@router.post("")
|
||||
@super_required
|
||||
def upload_to_media(request, image: File[UploadedFile]):
|
||||
# 生成唯一的文件名
|
||||
ext = Path(image.name).suffix
|
||||
filename = f"{uuid.uuid4()}{ext}"
|
||||
|
||||
# 确保 media 目录存在
|
||||
media_root = Path(settings.MEDIA_ROOT)
|
||||
media_root.mkdir(exist_ok=True)
|
||||
|
||||
# 保存文件
|
||||
file_path = media_root / filename
|
||||
with open(file_path, "wb+") as f:
|
||||
for chunk in image.chunks():
|
||||
f.write(chunk)
|
||||
|
||||
# 返回文件URL
|
||||
return {"url": f"{settings.MEDIA_URL}{filename}"}
|
||||
Reference in New Issue
Block a user