Open emilt27 opened 6 years ago
I've figured out why it does not work. I have the following:
class AddItem(graphene.relay.ClientIDMutation):
class Input:
files = graphene.List(Upload)
expires = graphene.Date(required=True)
When I try to execute this mutation with wrong expires
value, it tries to return the error with serialized payloads. Here is a line where it tries to serialize: https://github.com/graphql-python/graphql-core/blob/master/graphql/execution/values.py#L73
Oops man, when solving the problem of the field "expires" the upload with multiple files is working well? I am evaluating this library. I wanted to know if it is stable considering that my application will use a lot of image uploads.
Do we have a solution for uploading multiple files together ?
I spend sometime on this and this is definitely working fine. I read https://medium.com/@dilipkumar/graphql-and-file-upload-using-react-and-node-js-c1d629e1b86b to understand the payload structure and just did what they asked me to do.
In summary, we have to put the following keys and values in form-data
operations:{"query": "mutation uploadFiles($files: [Upload]) {uploadFiles(files: $files) { success }", "variables": { "files": [null,null] }}
map:{ "0": ["variables.files.0"], "1": ["variables.files.1"]}
Additionally 0
key should contain the content of the first file and 1
should contain the content of the second file.
Here's how to create a test for Django, combining all the bits of information from above + some figuring out:
# test_upload.py
import random
import pytest
from django.core.files.uploadedfile import SimpleUploadedFile
def get_bytes(size: int) -> bytes:
return bytes(bytearray(random.getrandbits(8) for _ in range(size)))
UPLOAD_DOCUMENTS = """mutation uploadDocuments($documents: [Upload]!) {
uploadDocuments(documents: $documents) {
success
}
}"""
def test_upload():
# Note the keys: variablename dot index_number
documents = {
"documents.0": SimpleUploadedFile(
name="scanned contract.png",
content=get_bytes(1024),
content_type="image/png",
),
"documents.1": SimpleUploadedFile(
name="Invoice.pdf",
content=get_bytes(2048),
content_type="application/pdf",
),
}
response = file_graphql_query(
UPLOAD_DOCUMENTS, files=documents, variables={"documents": [None, None]}
)
assert response.json()["data"]["uploadDocuments"]["success"] is True
# schema.py
class uploadDocuments(graphene.Mutation):
success = graphene.Boolean()
class Arguments:
documents = graphene.NonNull(graphene.List(Upload))
@classmethod
def mutate(
cls,
root,
info: td.ResolveInfo,
documents: t.List[SimpleUploadedFile],
):
if isinstance(documents[0], SimpleUploadedFile) and isinstance(
documents[1], SimpleUploadedFile
):
return cls(success=True)
return cls(success=False)
The question in title ^^.