improve upload error display

This commit is contained in:
Thomas Girod 2025-04-09 12:33:40 +02:00
parent 376af35bfb
commit 2c7b94547c
2 changed files with 19 additions and 4 deletions

View File

@ -1,9 +1,10 @@
from typing import Any, Literal
from django.conf import settings from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db.models import F from django.db.models import F
from django.urls import reverse from django.urls import reverse
from ninja import Body, File, Query from ninja import Body, File, Query
from ninja.errors import HttpError
from ninja_extra import ControllerBase, api_controller, paginate, route from ninja_extra import ControllerBase, api_controller, paginate, route
from ninja_extra.exceptions import NotFound, PermissionDenied from ninja_extra.exceptions import NotFound, PermissionDenied
from ninja_extra.pagination import PageNumberPaginationExtra from ninja_extra.pagination import PageNumberPaginationExtra
@ -104,7 +105,11 @@ class PicturesController(ControllerBase):
@route.post( @route.post(
"", "",
permissions=[CanEdit], permissions=[CanEdit],
response={200: None, 409: dict[str, list[str]]}, response={
200: None,
409: dict[Literal["detail"], dict[str, list[str]]],
422: dict[Literal["detail"], list[dict[str, Any]]],
},
url_name="upload_picture", url_name="upload_picture",
) )
def upload_picture(self, album_id: Body[int], picture: File[UploadedImage]): def upload_picture(self, album_id: Body[int], picture: File[UploadedImage]):
@ -127,7 +132,7 @@ class PicturesController(ControllerBase):
new.full_clean() new.full_clean()
new.save() new.save()
except ValidationError as e: except ValidationError as e:
raise HttpError(status_code=409, message=str(e)) from e return self.create_response({"detail": dict(e)}, status_code=409)
@route.get( @route.get(
"/{picture_id}/identified", "/{picture_id}/identified",

View File

@ -5,6 +5,7 @@ import {
type AlbumSchema, type AlbumSchema,
type PictureSchema, type PictureSchema,
type PicturesFetchPicturesData, type PicturesFetchPicturesData,
type PicturesUploadPictureErrors,
albumFetchAlbum, albumFetchAlbum,
picturesFetchPictures, picturesFetchPictures,
picturesUploadPicture, picturesUploadPicture,
@ -93,6 +94,7 @@ document.addEventListener("alpine:init", () => {
async sendPictures() { async sendPictures() {
const input = this.$refs.pictures as HTMLInputElement; const input = this.$refs.pictures as HTMLInputElement;
const files = input.files; const files = input.files;
this.errors = [];
this.progress.value = 0; this.progress.value = 0;
this.progress.max = files.length; this.progress.max = files.length;
this.sending = true; this.sending = true;
@ -110,7 +112,15 @@ document.addEventListener("alpine:init", () => {
body: { album_id: albumId, picture: file }, body: { album_id: albumId, picture: file },
}); });
if (!res.response.ok) { if (!res.response.ok) {
this.errors.push(`${file.name} : ${res.error.detail}`); let msg = "";
if (res.response.status === 422) {
msg = (res.error as PicturesUploadPictureErrors[422]).detail
.map((err: Record<"ctx", Record<"error", string>>) => err.ctx.error)
.join(" ; ");
} else {
msg = Object.values(res.error.detail).join(" ; ");
}
this.errors.push(`${file.name} : ${msg}`);
} }
this.progress.value += 1; this.progress.value += 1;
}, },