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.