I can't upload an image to my database at all
I'm using django ninja back end the code works but when I try to send it through an application that I'm making using javascript or even with bash it doesn't work
i've tryed
`def upload_media(request, nome:str, imgurl: UploadedFile ):
usuarios = Media.objects.all()
Media.objects.create(nome = nome,imgurl=imgurl)
return 1`
and
class mediaSchema(Schema): nome : str imgurl: UploadedFile
`@api.post('tst/', response=mediaSchema) def upload_media2(request, infos : mediaSchema):
media = infos.dict() infos = Media(**media)
infos.save()
return 1`
Issues with code:
The UploadedFile type in imgurl isn't handled correctly.UploadedFile must be managed through Django's request.FILES, not directly as a parameter. The function retrieves usuarios = Media.objects.all() but doesn’t use it. This line is redundant. Also there’s no error handling for file uploads or invalid data. lasn but not least, the return value 1 is not meaningful.
from django.http import JsonResponse from django.core.files.uploadedfile import UploadedFile def upload_media(request, nome: str, imgurl: UploadedFile): if request.method != "POST": return JsonResponse({"error": "Only POST method allowed"}, status=405) # Ensure file is uploaded via request.FILES if not request.FILES.get("imgurl"): return JsonResponse({"error": "File not uploaded"}, status=400) # Save the uploaded file imgurl = request.FILES["imgurl"] # Retrieve the file from request media = Media.objects.create(nome=nome, imgurl=imgurl) return JsonResponse({"message": "Media uploaded successfully", "media_id": media.id})class mediaSchema and upload_media2 issues: UploadedFile in mediaSchema doesn't work as expected with Django Ninja. Ninja uses File(...) to handle file uploads. infos.dict() won't handle UploadedFile properly because it isn’t a serializable field. Attempting to directly create a Media object from mediaSchema (Media(**media)) is incorrect because imgurl is not a compatible field
from ninja import Schema, File from django.core.files.uploadedfile import UploadedFile from ninja import ModelSchema class MediaSchema(Schema): nome: str imgurl: UploadedFile @api.post('tst/', response={200: str, 400: str}) def upload_media2(request, nome: str, imgurl: UploadedFile = File(...)): try: media = Media.objects.create(nome=nome, imgurl=imgurl) return 200, "Media uploaded successfully!" except Exception as e: return 400, f"Error occurred: {str(e)}"
The problem is that you didn't declare the schema correctly in the first case, file, should be specified separately, you did it correctly, and all the other (additional) fields should have been specified as Form schema, not as nome:str. So, in the first case, your controller should look something like this:
from ninja import Form, Schema, UploadedFile
app = NinjaAPI()
class UserDetailsSchema(Schema):
username: str
@app.post("/upload/")
def upload_media(request, details: Form[UserDetailsSchema], input_file: UploadedFile):
return {'username': details.username, 'file_name': input_file.name}
The result will be roughly the following code to send using javascript:
formData.append('username', 'Alex');
formData.append('input_file', file);
await fetch('http://127.0.0.1:8000/usuarios/api/upload/', {
body:formData,
method: 'POST',
// something extra
}).then(response=> response.json()).then(result => console.log(result))
// console.log output => {username: 'Alex', file_name: 'test.png'}
Or it could be done using another option:
from ninja import File, Schema, UploadedFile
app = NinjaAPI()
class UserDetailsSchema(Schema):
username: str
@app.post("/upload/")
def upload_media(
request,
details: UserDetailsSchema,
# or => input_file: UploadedFile
input_file: File[UploadedFile]):
return {'details': details, 'file_name': input_file.name}
Accordingly, the code to send the data to javascript should look something like this:
formData.append('details', JSON.stringify({ username: 'Alex' }));
formData.append('input_file', file);
await fetch('http://127.0.0.1:8000/usuarios/api/upload/', {
body:formData,
method: 'POST',
}).then(response=> response.json()).then(result => console.log(result))
// console.log output => {details: {username: 'Alex'}, file_name: 'test.png'}
That should work, in general the documentation seems to give clear examples I think.