Multiple file upload DRFDjango REST: Uploading and serializing multiple imagesmultiple file upload in django rest frameworkHow do I check whether a file exists without exceptions?How do I list all files of a directory?Need a minimal Django file upload exampleShow information of subclass in list_display djangoCatch multiple exceptions in one line (except block)Radio buttons in django adminHow to expose some specific fields of model_b based on a field of model_a?How to define Mode with generic ForeignKey in DjangoHow to implement update_or_create inside create method of ModelSerializerHow to check if Django Signal works?
Would life always name the light from their sun "white"
Is there any deeper thematic meaning to the white horse that Arya finds in The Bells (S08E05)?
Why doesn't Iron Man's action affect this person in Endgame?
Can anyone give me examples of the relative-determinative 'which'?
Why did the soldiers of the North disobey Jon?
the correct order of manual install WP and SSL on server
How could it be that 80% of townspeople were farmers during the Edo period in Japan?
Is the seat-belt sign activation when a pilot goes to the lavatory standard procedure?
What do you call the hair or body hair you trim off your body?
Why are goodwill impairments on the statement of cash-flows of GE?
With today's technology, could iron be smelted at La Rinconada?
Given 0s on Assignments with suspected and dismissed cheating?
How do I know which cipher suites can be disabled?
How to rename multiple files in a directory at the same time
labelled end points on logic diagram
Should I communicate in my applications that I'm unemployed out of choice rather than because nobody will have me?
What dog breeds survive the apocalypse for generations?
What is this weird d12 for?
Why did the metro bus stop at each railway crossing, despite no warning indicating a train was coming?
Why were the bells ignored in S8E5?
When did game consoles begin including FPUs?
Why does SSL Labs now consider CBC suites weak?
Slice a list based on an index and items behind it in python
God-Pharaoh's Statue and Finale Of Promise
Multiple file upload DRF
Django REST: Uploading and serializing multiple imagesmultiple file upload in django rest frameworkHow do I check whether a file exists without exceptions?How do I list all files of a directory?Need a minimal Django file upload exampleShow information of subclass in list_display djangoCatch multiple exceptions in one line (except block)Radio buttons in django adminHow to expose some specific fields of model_b based on a field of model_a?How to define Mode with generic ForeignKey in DjangoHow to implement update_or_create inside create method of ModelSerializerHow to check if Django Signal works?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I have a requirement which I would like to allow multiple files to be uploaded within the same post request to create an object. I currently have a method of doing this, but after looking at some other examples it doesn't appear to be intended way to do it.
models.py
class Analyzer(models.Model):
name = models.CharField(max_length=100, editable=False, unique=True)
class Atomic(models.Model):
name = models.CharField(max_length=20, unique=True)
class Submission(models.Model):
class Meta:
ordering = ['-updated_at']
issued_at = models.DateTimeField(auto_now_add=True, editable=False)
completed = models.BooleanField(default=False)
analyzers = models.ManyToManyField(Analyzer, related_name='submissions')
atomic = models.ForeignKey(Atomic, verbose_name='Atomic datatype', related_name='submission', on_delete=models.CASCADE)
class BinaryFile(models.Model):
class Meta:
verbose_name = 'Binary file'
verbose_name_plural = 'Binary files'
def __str__(self):
return self.file.name
submission = models.ForeignKey(Submission, on_delete=models.CASCADE, related_name='binary_files')
file = models.FileField(upload_to='uploads/binary/')
serializers.py
class BinaryFileSerializer(serializers.ModelSerializer):
class Meta:
model = models.BinaryFile
fields = '__all__'
class SubmissionCreateSerializer(serializers.ModelSerializer):
class Meta:
model = models.Submission
fields = ['id', 'completed', 'atomic', 'analyzers', 'binary_files']
id = serializers.ReadOnlyField()
completed = serializers.ReadOnlyField()
atomic = serializers.PrimaryKeyRelatedField(many=False, queryset=models.Atomic.objects.all()
analyzers = serializers.PrimaryKeyRelatedField(many=True, queryset=models.Analyzer.objects.all()
binary_files = BinaryFileSerializer(required=True, many=True)
def validate(self, data):
# # I dont really like manually taking invalidated input!!
data['binary_files'] = self.initial_data.getlist('binary_files')
return data
def create(self, validated_data):
submission = models.Submission.objects.create(
atomic=validated_data['atomic']
)
submission.analyzers.set(validated_data['analyzers'])
# # Serialize the files - this seems too late to be doing this!
for file in validated_data['binary_files']:
binary_file = BinaryFileSerializer(
data='file': file, 'submission': submission.id
)
if binary_file.is_valid():
binary_file.save()
return submission
Main question: While the above works, the child serializer (BinaryFileSerializer) doesn't get called until I explicitly call it in create(), which is after the validation should have occurred. Why does this never get called?
I also don't like the fact I have to manually do a self.initial_data.getlist('binary_files') and manually add it to data - this should have already been added and validated, no?
My thought is that as I defined binary_files = BinaryFileSerializer, this serializer should be called to validate that particular fields input?
FYI, I'm using the following to test POST uploads:
curl -F "binary_files=@file2.txt" -F "binary_files=@file2.txt" -F "atomic=7" -F "analyzers=12" -H "Accept: application/json; indent=4" http://127.0.0.1:8000/api/submit/
TIA!
Update: The question is now, if a validate() funciton is added to the BinaryFileSerializer, why does it not get called?
python django validation django-rest-framework upload
add a comment |
I have a requirement which I would like to allow multiple files to be uploaded within the same post request to create an object. I currently have a method of doing this, but after looking at some other examples it doesn't appear to be intended way to do it.
models.py
class Analyzer(models.Model):
name = models.CharField(max_length=100, editable=False, unique=True)
class Atomic(models.Model):
name = models.CharField(max_length=20, unique=True)
class Submission(models.Model):
class Meta:
ordering = ['-updated_at']
issued_at = models.DateTimeField(auto_now_add=True, editable=False)
completed = models.BooleanField(default=False)
analyzers = models.ManyToManyField(Analyzer, related_name='submissions')
atomic = models.ForeignKey(Atomic, verbose_name='Atomic datatype', related_name='submission', on_delete=models.CASCADE)
class BinaryFile(models.Model):
class Meta:
verbose_name = 'Binary file'
verbose_name_plural = 'Binary files'
def __str__(self):
return self.file.name
submission = models.ForeignKey(Submission, on_delete=models.CASCADE, related_name='binary_files')
file = models.FileField(upload_to='uploads/binary/')
serializers.py
class BinaryFileSerializer(serializers.ModelSerializer):
class Meta:
model = models.BinaryFile
fields = '__all__'
class SubmissionCreateSerializer(serializers.ModelSerializer):
class Meta:
model = models.Submission
fields = ['id', 'completed', 'atomic', 'analyzers', 'binary_files']
id = serializers.ReadOnlyField()
completed = serializers.ReadOnlyField()
atomic = serializers.PrimaryKeyRelatedField(many=False, queryset=models.Atomic.objects.all()
analyzers = serializers.PrimaryKeyRelatedField(many=True, queryset=models.Analyzer.objects.all()
binary_files = BinaryFileSerializer(required=True, many=True)
def validate(self, data):
# # I dont really like manually taking invalidated input!!
data['binary_files'] = self.initial_data.getlist('binary_files')
return data
def create(self, validated_data):
submission = models.Submission.objects.create(
atomic=validated_data['atomic']
)
submission.analyzers.set(validated_data['analyzers'])
# # Serialize the files - this seems too late to be doing this!
for file in validated_data['binary_files']:
binary_file = BinaryFileSerializer(
data='file': file, 'submission': submission.id
)
if binary_file.is_valid():
binary_file.save()
return submission
Main question: While the above works, the child serializer (BinaryFileSerializer) doesn't get called until I explicitly call it in create(), which is after the validation should have occurred. Why does this never get called?
I also don't like the fact I have to manually do a self.initial_data.getlist('binary_files') and manually add it to data - this should have already been added and validated, no?
My thought is that as I defined binary_files = BinaryFileSerializer, this serializer should be called to validate that particular fields input?
FYI, I'm using the following to test POST uploads:
curl -F "binary_files=@file2.txt" -F "binary_files=@file2.txt" -F "atomic=7" -F "analyzers=12" -H "Accept: application/json; indent=4" http://127.0.0.1:8000/api/submit/
TIA!
Update: The question is now, if a validate() funciton is added to the BinaryFileSerializer, why does it not get called?
python django validation django-rest-framework upload
This is an interesting problem! I am thinking about how it is being serialized because each instance of the serializer has room for 1 'binary_file' and youre sending multiple fields labeled as 'binary_file.' I am wondering how the serializer is handling this, my fear is that it either saves the first or the last and the rest get thrown out. You could possibly fix this by having your view have 2 serializers, one to handle the files, the other for the remaining information. The serializer for the files could then loop for each occurrence of 'binary_file' and return an array of files?
– Scott Glascott
Mar 23 at 22:20
In terms of what it keeps, nothing 😀. I never get binary_files in the validated_data, if I send 1, 2, or more fields!
– geekscrap
Mar 24 at 11:51
I'm very new to DRF (and pretty new to Django), but I didn't know I could use multiple serializers! Can you link me?
– geekscrap
Mar 24 at 11:52
add a comment |
I have a requirement which I would like to allow multiple files to be uploaded within the same post request to create an object. I currently have a method of doing this, but after looking at some other examples it doesn't appear to be intended way to do it.
models.py
class Analyzer(models.Model):
name = models.CharField(max_length=100, editable=False, unique=True)
class Atomic(models.Model):
name = models.CharField(max_length=20, unique=True)
class Submission(models.Model):
class Meta:
ordering = ['-updated_at']
issued_at = models.DateTimeField(auto_now_add=True, editable=False)
completed = models.BooleanField(default=False)
analyzers = models.ManyToManyField(Analyzer, related_name='submissions')
atomic = models.ForeignKey(Atomic, verbose_name='Atomic datatype', related_name='submission', on_delete=models.CASCADE)
class BinaryFile(models.Model):
class Meta:
verbose_name = 'Binary file'
verbose_name_plural = 'Binary files'
def __str__(self):
return self.file.name
submission = models.ForeignKey(Submission, on_delete=models.CASCADE, related_name='binary_files')
file = models.FileField(upload_to='uploads/binary/')
serializers.py
class BinaryFileSerializer(serializers.ModelSerializer):
class Meta:
model = models.BinaryFile
fields = '__all__'
class SubmissionCreateSerializer(serializers.ModelSerializer):
class Meta:
model = models.Submission
fields = ['id', 'completed', 'atomic', 'analyzers', 'binary_files']
id = serializers.ReadOnlyField()
completed = serializers.ReadOnlyField()
atomic = serializers.PrimaryKeyRelatedField(many=False, queryset=models.Atomic.objects.all()
analyzers = serializers.PrimaryKeyRelatedField(many=True, queryset=models.Analyzer.objects.all()
binary_files = BinaryFileSerializer(required=True, many=True)
def validate(self, data):
# # I dont really like manually taking invalidated input!!
data['binary_files'] = self.initial_data.getlist('binary_files')
return data
def create(self, validated_data):
submission = models.Submission.objects.create(
atomic=validated_data['atomic']
)
submission.analyzers.set(validated_data['analyzers'])
# # Serialize the files - this seems too late to be doing this!
for file in validated_data['binary_files']:
binary_file = BinaryFileSerializer(
data='file': file, 'submission': submission.id
)
if binary_file.is_valid():
binary_file.save()
return submission
Main question: While the above works, the child serializer (BinaryFileSerializer) doesn't get called until I explicitly call it in create(), which is after the validation should have occurred. Why does this never get called?
I also don't like the fact I have to manually do a self.initial_data.getlist('binary_files') and manually add it to data - this should have already been added and validated, no?
My thought is that as I defined binary_files = BinaryFileSerializer, this serializer should be called to validate that particular fields input?
FYI, I'm using the following to test POST uploads:
curl -F "binary_files=@file2.txt" -F "binary_files=@file2.txt" -F "atomic=7" -F "analyzers=12" -H "Accept: application/json; indent=4" http://127.0.0.1:8000/api/submit/
TIA!
Update: The question is now, if a validate() funciton is added to the BinaryFileSerializer, why does it not get called?
python django validation django-rest-framework upload
I have a requirement which I would like to allow multiple files to be uploaded within the same post request to create an object. I currently have a method of doing this, but after looking at some other examples it doesn't appear to be intended way to do it.
models.py
class Analyzer(models.Model):
name = models.CharField(max_length=100, editable=False, unique=True)
class Atomic(models.Model):
name = models.CharField(max_length=20, unique=True)
class Submission(models.Model):
class Meta:
ordering = ['-updated_at']
issued_at = models.DateTimeField(auto_now_add=True, editable=False)
completed = models.BooleanField(default=False)
analyzers = models.ManyToManyField(Analyzer, related_name='submissions')
atomic = models.ForeignKey(Atomic, verbose_name='Atomic datatype', related_name='submission', on_delete=models.CASCADE)
class BinaryFile(models.Model):
class Meta:
verbose_name = 'Binary file'
verbose_name_plural = 'Binary files'
def __str__(self):
return self.file.name
submission = models.ForeignKey(Submission, on_delete=models.CASCADE, related_name='binary_files')
file = models.FileField(upload_to='uploads/binary/')
serializers.py
class BinaryFileSerializer(serializers.ModelSerializer):
class Meta:
model = models.BinaryFile
fields = '__all__'
class SubmissionCreateSerializer(serializers.ModelSerializer):
class Meta:
model = models.Submission
fields = ['id', 'completed', 'atomic', 'analyzers', 'binary_files']
id = serializers.ReadOnlyField()
completed = serializers.ReadOnlyField()
atomic = serializers.PrimaryKeyRelatedField(many=False, queryset=models.Atomic.objects.all()
analyzers = serializers.PrimaryKeyRelatedField(many=True, queryset=models.Analyzer.objects.all()
binary_files = BinaryFileSerializer(required=True, many=True)
def validate(self, data):
# # I dont really like manually taking invalidated input!!
data['binary_files'] = self.initial_data.getlist('binary_files')
return data
def create(self, validated_data):
submission = models.Submission.objects.create(
atomic=validated_data['atomic']
)
submission.analyzers.set(validated_data['analyzers'])
# # Serialize the files - this seems too late to be doing this!
for file in validated_data['binary_files']:
binary_file = BinaryFileSerializer(
data='file': file, 'submission': submission.id
)
if binary_file.is_valid():
binary_file.save()
return submission
Main question: While the above works, the child serializer (BinaryFileSerializer) doesn't get called until I explicitly call it in create(), which is after the validation should have occurred. Why does this never get called?
I also don't like the fact I have to manually do a self.initial_data.getlist('binary_files') and manually add it to data - this should have already been added and validated, no?
My thought is that as I defined binary_files = BinaryFileSerializer, this serializer should be called to validate that particular fields input?
FYI, I'm using the following to test POST uploads:
curl -F "binary_files=@file2.txt" -F "binary_files=@file2.txt" -F "atomic=7" -F "analyzers=12" -H "Accept: application/json; indent=4" http://127.0.0.1:8000/api/submit/
TIA!
Update: The question is now, if a validate() funciton is added to the BinaryFileSerializer, why does it not get called?
python django validation django-rest-framework upload
python django validation django-rest-framework upload
edited Mar 26 at 22:47
geekscrap
asked Mar 23 at 15:11
geekscrapgeekscrap
1392220
1392220
This is an interesting problem! I am thinking about how it is being serialized because each instance of the serializer has room for 1 'binary_file' and youre sending multiple fields labeled as 'binary_file.' I am wondering how the serializer is handling this, my fear is that it either saves the first or the last and the rest get thrown out. You could possibly fix this by having your view have 2 serializers, one to handle the files, the other for the remaining information. The serializer for the files could then loop for each occurrence of 'binary_file' and return an array of files?
– Scott Glascott
Mar 23 at 22:20
In terms of what it keeps, nothing 😀. I never get binary_files in the validated_data, if I send 1, 2, or more fields!
– geekscrap
Mar 24 at 11:51
I'm very new to DRF (and pretty new to Django), but I didn't know I could use multiple serializers! Can you link me?
– geekscrap
Mar 24 at 11:52
add a comment |
This is an interesting problem! I am thinking about how it is being serialized because each instance of the serializer has room for 1 'binary_file' and youre sending multiple fields labeled as 'binary_file.' I am wondering how the serializer is handling this, my fear is that it either saves the first or the last and the rest get thrown out. You could possibly fix this by having your view have 2 serializers, one to handle the files, the other for the remaining information. The serializer for the files could then loop for each occurrence of 'binary_file' and return an array of files?
– Scott Glascott
Mar 23 at 22:20
In terms of what it keeps, nothing 😀. I never get binary_files in the validated_data, if I send 1, 2, or more fields!
– geekscrap
Mar 24 at 11:51
I'm very new to DRF (and pretty new to Django), but I didn't know I could use multiple serializers! Can you link me?
– geekscrap
Mar 24 at 11:52
This is an interesting problem! I am thinking about how it is being serialized because each instance of the serializer has room for 1 'binary_file' and youre sending multiple fields labeled as 'binary_file.' I am wondering how the serializer is handling this, my fear is that it either saves the first or the last and the rest get thrown out. You could possibly fix this by having your view have 2 serializers, one to handle the files, the other for the remaining information. The serializer for the files could then loop for each occurrence of 'binary_file' and return an array of files?
– Scott Glascott
Mar 23 at 22:20
This is an interesting problem! I am thinking about how it is being serialized because each instance of the serializer has room for 1 'binary_file' and youre sending multiple fields labeled as 'binary_file.' I am wondering how the serializer is handling this, my fear is that it either saves the first or the last and the rest get thrown out. You could possibly fix this by having your view have 2 serializers, one to handle the files, the other for the remaining information. The serializer for the files could then loop for each occurrence of 'binary_file' and return an array of files?
– Scott Glascott
Mar 23 at 22:20
In terms of what it keeps, nothing 😀. I never get binary_files in the validated_data, if I send 1, 2, or more fields!
– geekscrap
Mar 24 at 11:51
In terms of what it keeps, nothing 😀. I never get binary_files in the validated_data, if I send 1, 2, or more fields!
– geekscrap
Mar 24 at 11:51
I'm very new to DRF (and pretty new to Django), but I didn't know I could use multiple serializers! Can you link me?
– geekscrap
Mar 24 at 11:52
I'm very new to DRF (and pretty new to Django), but I didn't know I could use multiple serializers! Can you link me?
– geekscrap
Mar 24 at 11:52
add a comment |
1 Answer
1
active
oldest
votes
Possible duplicate --- Django REST: Uploading and serializing multiple images.
From the DRF Writable Nested Serializer doc,
By default nested serializers are read-only. If you want to support write-operations to a nested serializer field you'll need to create
create()and/orupdate()methods in order to explicitly specify how the child relationships should be saved.
From this, it's clear that the child serializer (BinaryFileSerializer) won't call its own create() method unless explicitly called.
The aim of your HTTP POST request is to create new Submission instance (and BinaryFile instance). The creation process undergoes in the create() method of the SubmissionCreateSerializer serializer, which is you'd overridden. So, it will act/execute as per your code.
UPDATE-1
Things to remember
1. AFAIK, we can't send nested multipart/form-data
2. Here I'm only trying to implementing the least case scenario
3. I'm tested this solution with POSTMAN rest api test tool.
4. This method may be complex (until we found a better one).
5. Assuming your view class is subclass of ModelViewSet class
What I'm going to do?
1. Since we can't send the files/data in a nested fashion, we have to send it flat mode.
image-1
2. Override the __init__() method of the SubmissionSerializer serializer and dynamically add as much FileField() attribute according to the request.FILES data.
We could somehow use ListSerializer or ListField here. Unfortunately I couldn't find out a way :(
# init method of "SubmissionSerializer"
def __init__(self, *args, **kwargs):
file_fields = kwargs.pop('file_fields', None)
super().__init__(*args, **kwargs)
if file_fields:
field_update_dict = field: serializers.FileField(required=False, write_only=True) for field in file_fields
self.fields.update(**field_update_dict)
So, what id file_fields here?
Since the form-data is a key-value pair, every file data must be associated with a key. Here in image-1, you could see file_1 and file_2.
3. Now we need to pass the file_fields values from the view. Since this operation is creating new instance, we need to override the create() method of the API class.
# complete view code
from rest_framework import status
from rest_framework import viewsets
class SubmissionAPI(viewsets.ModelViewSet):
queryset = Submission.objects.all()
serializer_class = SubmissionSerializer
def create(self, request, *args, **kwargs):
# main thing starts
file_fields = list(request.FILES.keys()) # list to be passed to the serializer
serializer = self.get_serializer(data=request.data, file_fields=file_fields)
# main thing ends
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
4. Now, all values will be serialized properly. It's time to override the create() method of the SubmissionSerializer() to map the relations
def create(self, validated_data):
from django.core.files.uploadedfile import InMemoryUploadedFile
validated_data_copy = validated_data.copy()
validated_files = []
for key, value in validated_data_copy.items():
if isinstance(value, InMemoryUploadedFile):
validated_files.append(value)
validated_data.pop(key)
submission_instance = super().create(validated_data)
for file in validated_files:
BinaryFile.objects.create(submission=submission_instance, file=file)
return submission_instance
5. That's it!!!
Complete Code Snippet
# serializers.py
from rest_framework import serializers
from django.core.files.uploadedfile import InMemoryUploadedFile
class SubmissionSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
file_fields = kwargs.pop('file_fields', None)
super().__init__(*args, **kwargs)
if file_fields:
field_update_dict = field: serializers.FileField(required=False, write_only=True) for field in file_fields
self.fields.update(**field_update_dict)
def create(self, validated_data):
validated_data_copy = validated_data.copy()
validated_files = []
for key, value in validated_data_copy.items():
if isinstance(value, InMemoryUploadedFile):
validated_files.append(value)
validated_data.pop(key)
submission_instance = super().create(validated_data)
for file in validated_files:
BinaryFile.objects.create(submission=submission_instance, file=file)
return submission_instance
class Meta:
model = Submission
fields = '__all__'
# views.py
from rest_framework import status
from rest_framework import viewsets
class SubmissionAPI(viewsets.ModelViewSet):
queryset = Submission.objects.all()
serializer_class = SubmissionSerializer
def create(self, request, *args, **kwargs):
# main thing starts
file_fields = list(request.FILES.keys()) # list to be passed to the serializer
serializer = self.get_serializer(data=request.data, file_fields=file_fields)
# main thing ends
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)Screenhots and other stuffs
1. POSTMAN console
2. Django Shell
In [2]: Submission.objects.all()
Out[2]: <QuerySet [<Submission: Submission object>]>
In [3]: sub_obj = Submission.objects.all()[0]
In [4]: sub_obj
Out[4]: <Submission: Submission object>
In [5]: sub_obj.__dict__
Out[5]:
'_state': <django.db.models.base.ModelState at 0x7f529a7ea240>,
'id': 5,
'issued_at': datetime.datetime(2019, 3, 27, 8, 45, 42, 193943, tzinfo=<UTC>),
'completed': False,
'atomic_id': 1
In [6]: sub_obj.binary_files.all()
Out[6]: <QuerySet [<BinaryFile: uploads/binary/logo-800.png>, <BinaryFile: uploads/binary/Doc.pdf>, <BinaryFile: uploads/binary/invoice_2018_11_29_04_57_53.pdf>, <BinaryFile: uploads/binary/Screenshot_from_2019-02-13_16-22-53.png>]>
In [7]: for _ in sub_obj.binary_files.all():
...: print(_)
...:
uploads/binary/logo-800.png
uploads/binary/Doc.pdf
uploads/binary/invoice_2018_11_29_04_57_53.pdf
uploads/binary/Screenshot_from_2019-02-13_16-22-53.png
3. Django Admin Screenhot
Not a duplicate as far as I can see. I get what you say, which is why I have created a create() function in SubmissionCreateSerializer() and created the BinaryFile object there. I guess my question becomes, with the models above, how do I apply validation to the child serializer?
– geekscrap
Mar 26 at 22:45
@geekscrap Check the updated answer :)
– JPG
Mar 27 at 9:08
@geekscrap did you try this?
– JPG
Mar 29 at 1:43
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55315158%2fmultiple-file-upload-drf%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Possible duplicate --- Django REST: Uploading and serializing multiple images.
From the DRF Writable Nested Serializer doc,
By default nested serializers are read-only. If you want to support write-operations to a nested serializer field you'll need to create
create()and/orupdate()methods in order to explicitly specify how the child relationships should be saved.
From this, it's clear that the child serializer (BinaryFileSerializer) won't call its own create() method unless explicitly called.
The aim of your HTTP POST request is to create new Submission instance (and BinaryFile instance). The creation process undergoes in the create() method of the SubmissionCreateSerializer serializer, which is you'd overridden. So, it will act/execute as per your code.
UPDATE-1
Things to remember
1. AFAIK, we can't send nested multipart/form-data
2. Here I'm only trying to implementing the least case scenario
3. I'm tested this solution with POSTMAN rest api test tool.
4. This method may be complex (until we found a better one).
5. Assuming your view class is subclass of ModelViewSet class
What I'm going to do?
1. Since we can't send the files/data in a nested fashion, we have to send it flat mode.
image-1
2. Override the __init__() method of the SubmissionSerializer serializer and dynamically add as much FileField() attribute according to the request.FILES data.
We could somehow use ListSerializer or ListField here. Unfortunately I couldn't find out a way :(
# init method of "SubmissionSerializer"
def __init__(self, *args, **kwargs):
file_fields = kwargs.pop('file_fields', None)
super().__init__(*args, **kwargs)
if file_fields:
field_update_dict = field: serializers.FileField(required=False, write_only=True) for field in file_fields
self.fields.update(**field_update_dict)
So, what id file_fields here?
Since the form-data is a key-value pair, every file data must be associated with a key. Here in image-1, you could see file_1 and file_2.
3. Now we need to pass the file_fields values from the view. Since this operation is creating new instance, we need to override the create() method of the API class.
# complete view code
from rest_framework import status
from rest_framework import viewsets
class SubmissionAPI(viewsets.ModelViewSet):
queryset = Submission.objects.all()
serializer_class = SubmissionSerializer
def create(self, request, *args, **kwargs):
# main thing starts
file_fields = list(request.FILES.keys()) # list to be passed to the serializer
serializer = self.get_serializer(data=request.data, file_fields=file_fields)
# main thing ends
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
4. Now, all values will be serialized properly. It's time to override the create() method of the SubmissionSerializer() to map the relations
def create(self, validated_data):
from django.core.files.uploadedfile import InMemoryUploadedFile
validated_data_copy = validated_data.copy()
validated_files = []
for key, value in validated_data_copy.items():
if isinstance(value, InMemoryUploadedFile):
validated_files.append(value)
validated_data.pop(key)
submission_instance = super().create(validated_data)
for file in validated_files:
BinaryFile.objects.create(submission=submission_instance, file=file)
return submission_instance
5. That's it!!!
Complete Code Snippet
# serializers.py
from rest_framework import serializers
from django.core.files.uploadedfile import InMemoryUploadedFile
class SubmissionSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
file_fields = kwargs.pop('file_fields', None)
super().__init__(*args, **kwargs)
if file_fields:
field_update_dict = field: serializers.FileField(required=False, write_only=True) for field in file_fields
self.fields.update(**field_update_dict)
def create(self, validated_data):
validated_data_copy = validated_data.copy()
validated_files = []
for key, value in validated_data_copy.items():
if isinstance(value, InMemoryUploadedFile):
validated_files.append(value)
validated_data.pop(key)
submission_instance = super().create(validated_data)
for file in validated_files:
BinaryFile.objects.create(submission=submission_instance, file=file)
return submission_instance
class Meta:
model = Submission
fields = '__all__'
# views.py
from rest_framework import status
from rest_framework import viewsets
class SubmissionAPI(viewsets.ModelViewSet):
queryset = Submission.objects.all()
serializer_class = SubmissionSerializer
def create(self, request, *args, **kwargs):
# main thing starts
file_fields = list(request.FILES.keys()) # list to be passed to the serializer
serializer = self.get_serializer(data=request.data, file_fields=file_fields)
# main thing ends
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)Screenhots and other stuffs
1. POSTMAN console
2. Django Shell
In [2]: Submission.objects.all()
Out[2]: <QuerySet [<Submission: Submission object>]>
In [3]: sub_obj = Submission.objects.all()[0]
In [4]: sub_obj
Out[4]: <Submission: Submission object>
In [5]: sub_obj.__dict__
Out[5]:
'_state': <django.db.models.base.ModelState at 0x7f529a7ea240>,
'id': 5,
'issued_at': datetime.datetime(2019, 3, 27, 8, 45, 42, 193943, tzinfo=<UTC>),
'completed': False,
'atomic_id': 1
In [6]: sub_obj.binary_files.all()
Out[6]: <QuerySet [<BinaryFile: uploads/binary/logo-800.png>, <BinaryFile: uploads/binary/Doc.pdf>, <BinaryFile: uploads/binary/invoice_2018_11_29_04_57_53.pdf>, <BinaryFile: uploads/binary/Screenshot_from_2019-02-13_16-22-53.png>]>
In [7]: for _ in sub_obj.binary_files.all():
...: print(_)
...:
uploads/binary/logo-800.png
uploads/binary/Doc.pdf
uploads/binary/invoice_2018_11_29_04_57_53.pdf
uploads/binary/Screenshot_from_2019-02-13_16-22-53.png
3. Django Admin Screenhot
Not a duplicate as far as I can see. I get what you say, which is why I have created a create() function in SubmissionCreateSerializer() and created the BinaryFile object there. I guess my question becomes, with the models above, how do I apply validation to the child serializer?
– geekscrap
Mar 26 at 22:45
@geekscrap Check the updated answer :)
– JPG
Mar 27 at 9:08
@geekscrap did you try this?
– JPG
Mar 29 at 1:43
add a comment |
Possible duplicate --- Django REST: Uploading and serializing multiple images.
From the DRF Writable Nested Serializer doc,
By default nested serializers are read-only. If you want to support write-operations to a nested serializer field you'll need to create
create()and/orupdate()methods in order to explicitly specify how the child relationships should be saved.
From this, it's clear that the child serializer (BinaryFileSerializer) won't call its own create() method unless explicitly called.
The aim of your HTTP POST request is to create new Submission instance (and BinaryFile instance). The creation process undergoes in the create() method of the SubmissionCreateSerializer serializer, which is you'd overridden. So, it will act/execute as per your code.
UPDATE-1
Things to remember
1. AFAIK, we can't send nested multipart/form-data
2. Here I'm only trying to implementing the least case scenario
3. I'm tested this solution with POSTMAN rest api test tool.
4. This method may be complex (until we found a better one).
5. Assuming your view class is subclass of ModelViewSet class
What I'm going to do?
1. Since we can't send the files/data in a nested fashion, we have to send it flat mode.
image-1
2. Override the __init__() method of the SubmissionSerializer serializer and dynamically add as much FileField() attribute according to the request.FILES data.
We could somehow use ListSerializer or ListField here. Unfortunately I couldn't find out a way :(
# init method of "SubmissionSerializer"
def __init__(self, *args, **kwargs):
file_fields = kwargs.pop('file_fields', None)
super().__init__(*args, **kwargs)
if file_fields:
field_update_dict = field: serializers.FileField(required=False, write_only=True) for field in file_fields
self.fields.update(**field_update_dict)
So, what id file_fields here?
Since the form-data is a key-value pair, every file data must be associated with a key. Here in image-1, you could see file_1 and file_2.
3. Now we need to pass the file_fields values from the view. Since this operation is creating new instance, we need to override the create() method of the API class.
# complete view code
from rest_framework import status
from rest_framework import viewsets
class SubmissionAPI(viewsets.ModelViewSet):
queryset = Submission.objects.all()
serializer_class = SubmissionSerializer
def create(self, request, *args, **kwargs):
# main thing starts
file_fields = list(request.FILES.keys()) # list to be passed to the serializer
serializer = self.get_serializer(data=request.data, file_fields=file_fields)
# main thing ends
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
4. Now, all values will be serialized properly. It's time to override the create() method of the SubmissionSerializer() to map the relations
def create(self, validated_data):
from django.core.files.uploadedfile import InMemoryUploadedFile
validated_data_copy = validated_data.copy()
validated_files = []
for key, value in validated_data_copy.items():
if isinstance(value, InMemoryUploadedFile):
validated_files.append(value)
validated_data.pop(key)
submission_instance = super().create(validated_data)
for file in validated_files:
BinaryFile.objects.create(submission=submission_instance, file=file)
return submission_instance
5. That's it!!!
Complete Code Snippet
# serializers.py
from rest_framework import serializers
from django.core.files.uploadedfile import InMemoryUploadedFile
class SubmissionSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
file_fields = kwargs.pop('file_fields', None)
super().__init__(*args, **kwargs)
if file_fields:
field_update_dict = field: serializers.FileField(required=False, write_only=True) for field in file_fields
self.fields.update(**field_update_dict)
def create(self, validated_data):
validated_data_copy = validated_data.copy()
validated_files = []
for key, value in validated_data_copy.items():
if isinstance(value, InMemoryUploadedFile):
validated_files.append(value)
validated_data.pop(key)
submission_instance = super().create(validated_data)
for file in validated_files:
BinaryFile.objects.create(submission=submission_instance, file=file)
return submission_instance
class Meta:
model = Submission
fields = '__all__'
# views.py
from rest_framework import status
from rest_framework import viewsets
class SubmissionAPI(viewsets.ModelViewSet):
queryset = Submission.objects.all()
serializer_class = SubmissionSerializer
def create(self, request, *args, **kwargs):
# main thing starts
file_fields = list(request.FILES.keys()) # list to be passed to the serializer
serializer = self.get_serializer(data=request.data, file_fields=file_fields)
# main thing ends
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)Screenhots and other stuffs
1. POSTMAN console
2. Django Shell
In [2]: Submission.objects.all()
Out[2]: <QuerySet [<Submission: Submission object>]>
In [3]: sub_obj = Submission.objects.all()[0]
In [4]: sub_obj
Out[4]: <Submission: Submission object>
In [5]: sub_obj.__dict__
Out[5]:
'_state': <django.db.models.base.ModelState at 0x7f529a7ea240>,
'id': 5,
'issued_at': datetime.datetime(2019, 3, 27, 8, 45, 42, 193943, tzinfo=<UTC>),
'completed': False,
'atomic_id': 1
In [6]: sub_obj.binary_files.all()
Out[6]: <QuerySet [<BinaryFile: uploads/binary/logo-800.png>, <BinaryFile: uploads/binary/Doc.pdf>, <BinaryFile: uploads/binary/invoice_2018_11_29_04_57_53.pdf>, <BinaryFile: uploads/binary/Screenshot_from_2019-02-13_16-22-53.png>]>
In [7]: for _ in sub_obj.binary_files.all():
...: print(_)
...:
uploads/binary/logo-800.png
uploads/binary/Doc.pdf
uploads/binary/invoice_2018_11_29_04_57_53.pdf
uploads/binary/Screenshot_from_2019-02-13_16-22-53.png
3. Django Admin Screenhot
Not a duplicate as far as I can see. I get what you say, which is why I have created a create() function in SubmissionCreateSerializer() and created the BinaryFile object there. I guess my question becomes, with the models above, how do I apply validation to the child serializer?
– geekscrap
Mar 26 at 22:45
@geekscrap Check the updated answer :)
– JPG
Mar 27 at 9:08
@geekscrap did you try this?
– JPG
Mar 29 at 1:43
add a comment |
Possible duplicate --- Django REST: Uploading and serializing multiple images.
From the DRF Writable Nested Serializer doc,
By default nested serializers are read-only. If you want to support write-operations to a nested serializer field you'll need to create
create()and/orupdate()methods in order to explicitly specify how the child relationships should be saved.
From this, it's clear that the child serializer (BinaryFileSerializer) won't call its own create() method unless explicitly called.
The aim of your HTTP POST request is to create new Submission instance (and BinaryFile instance). The creation process undergoes in the create() method of the SubmissionCreateSerializer serializer, which is you'd overridden. So, it will act/execute as per your code.
UPDATE-1
Things to remember
1. AFAIK, we can't send nested multipart/form-data
2. Here I'm only trying to implementing the least case scenario
3. I'm tested this solution with POSTMAN rest api test tool.
4. This method may be complex (until we found a better one).
5. Assuming your view class is subclass of ModelViewSet class
What I'm going to do?
1. Since we can't send the files/data in a nested fashion, we have to send it flat mode.
image-1
2. Override the __init__() method of the SubmissionSerializer serializer and dynamically add as much FileField() attribute according to the request.FILES data.
We could somehow use ListSerializer or ListField here. Unfortunately I couldn't find out a way :(
# init method of "SubmissionSerializer"
def __init__(self, *args, **kwargs):
file_fields = kwargs.pop('file_fields', None)
super().__init__(*args, **kwargs)
if file_fields:
field_update_dict = field: serializers.FileField(required=False, write_only=True) for field in file_fields
self.fields.update(**field_update_dict)
So, what id file_fields here?
Since the form-data is a key-value pair, every file data must be associated with a key. Here in image-1, you could see file_1 and file_2.
3. Now we need to pass the file_fields values from the view. Since this operation is creating new instance, we need to override the create() method of the API class.
# complete view code
from rest_framework import status
from rest_framework import viewsets
class SubmissionAPI(viewsets.ModelViewSet):
queryset = Submission.objects.all()
serializer_class = SubmissionSerializer
def create(self, request, *args, **kwargs):
# main thing starts
file_fields = list(request.FILES.keys()) # list to be passed to the serializer
serializer = self.get_serializer(data=request.data, file_fields=file_fields)
# main thing ends
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
4. Now, all values will be serialized properly. It's time to override the create() method of the SubmissionSerializer() to map the relations
def create(self, validated_data):
from django.core.files.uploadedfile import InMemoryUploadedFile
validated_data_copy = validated_data.copy()
validated_files = []
for key, value in validated_data_copy.items():
if isinstance(value, InMemoryUploadedFile):
validated_files.append(value)
validated_data.pop(key)
submission_instance = super().create(validated_data)
for file in validated_files:
BinaryFile.objects.create(submission=submission_instance, file=file)
return submission_instance
5. That's it!!!
Complete Code Snippet
# serializers.py
from rest_framework import serializers
from django.core.files.uploadedfile import InMemoryUploadedFile
class SubmissionSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
file_fields = kwargs.pop('file_fields', None)
super().__init__(*args, **kwargs)
if file_fields:
field_update_dict = field: serializers.FileField(required=False, write_only=True) for field in file_fields
self.fields.update(**field_update_dict)
def create(self, validated_data):
validated_data_copy = validated_data.copy()
validated_files = []
for key, value in validated_data_copy.items():
if isinstance(value, InMemoryUploadedFile):
validated_files.append(value)
validated_data.pop(key)
submission_instance = super().create(validated_data)
for file in validated_files:
BinaryFile.objects.create(submission=submission_instance, file=file)
return submission_instance
class Meta:
model = Submission
fields = '__all__'
# views.py
from rest_framework import status
from rest_framework import viewsets
class SubmissionAPI(viewsets.ModelViewSet):
queryset = Submission.objects.all()
serializer_class = SubmissionSerializer
def create(self, request, *args, **kwargs):
# main thing starts
file_fields = list(request.FILES.keys()) # list to be passed to the serializer
serializer = self.get_serializer(data=request.data, file_fields=file_fields)
# main thing ends
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)Screenhots and other stuffs
1. POSTMAN console
2. Django Shell
In [2]: Submission.objects.all()
Out[2]: <QuerySet [<Submission: Submission object>]>
In [3]: sub_obj = Submission.objects.all()[0]
In [4]: sub_obj
Out[4]: <Submission: Submission object>
In [5]: sub_obj.__dict__
Out[5]:
'_state': <django.db.models.base.ModelState at 0x7f529a7ea240>,
'id': 5,
'issued_at': datetime.datetime(2019, 3, 27, 8, 45, 42, 193943, tzinfo=<UTC>),
'completed': False,
'atomic_id': 1
In [6]: sub_obj.binary_files.all()
Out[6]: <QuerySet [<BinaryFile: uploads/binary/logo-800.png>, <BinaryFile: uploads/binary/Doc.pdf>, <BinaryFile: uploads/binary/invoice_2018_11_29_04_57_53.pdf>, <BinaryFile: uploads/binary/Screenshot_from_2019-02-13_16-22-53.png>]>
In [7]: for _ in sub_obj.binary_files.all():
...: print(_)
...:
uploads/binary/logo-800.png
uploads/binary/Doc.pdf
uploads/binary/invoice_2018_11_29_04_57_53.pdf
uploads/binary/Screenshot_from_2019-02-13_16-22-53.png
3. Django Admin Screenhot
Possible duplicate --- Django REST: Uploading and serializing multiple images.
From the DRF Writable Nested Serializer doc,
By default nested serializers are read-only. If you want to support write-operations to a nested serializer field you'll need to create
create()and/orupdate()methods in order to explicitly specify how the child relationships should be saved.
From this, it's clear that the child serializer (BinaryFileSerializer) won't call its own create() method unless explicitly called.
The aim of your HTTP POST request is to create new Submission instance (and BinaryFile instance). The creation process undergoes in the create() method of the SubmissionCreateSerializer serializer, which is you'd overridden. So, it will act/execute as per your code.
UPDATE-1
Things to remember
1. AFAIK, we can't send nested multipart/form-data
2. Here I'm only trying to implementing the least case scenario
3. I'm tested this solution with POSTMAN rest api test tool.
4. This method may be complex (until we found a better one).
5. Assuming your view class is subclass of ModelViewSet class
What I'm going to do?
1. Since we can't send the files/data in a nested fashion, we have to send it flat mode.
image-1
2. Override the __init__() method of the SubmissionSerializer serializer and dynamically add as much FileField() attribute according to the request.FILES data.
We could somehow use ListSerializer or ListField here. Unfortunately I couldn't find out a way :(
# init method of "SubmissionSerializer"
def __init__(self, *args, **kwargs):
file_fields = kwargs.pop('file_fields', None)
super().__init__(*args, **kwargs)
if file_fields:
field_update_dict = field: serializers.FileField(required=False, write_only=True) for field in file_fields
self.fields.update(**field_update_dict)
So, what id file_fields here?
Since the form-data is a key-value pair, every file data must be associated with a key. Here in image-1, you could see file_1 and file_2.
3. Now we need to pass the file_fields values from the view. Since this operation is creating new instance, we need to override the create() method of the API class.
# complete view code
from rest_framework import status
from rest_framework import viewsets
class SubmissionAPI(viewsets.ModelViewSet):
queryset = Submission.objects.all()
serializer_class = SubmissionSerializer
def create(self, request, *args, **kwargs):
# main thing starts
file_fields = list(request.FILES.keys()) # list to be passed to the serializer
serializer = self.get_serializer(data=request.data, file_fields=file_fields)
# main thing ends
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
4. Now, all values will be serialized properly. It's time to override the create() method of the SubmissionSerializer() to map the relations
def create(self, validated_data):
from django.core.files.uploadedfile import InMemoryUploadedFile
validated_data_copy = validated_data.copy()
validated_files = []
for key, value in validated_data_copy.items():
if isinstance(value, InMemoryUploadedFile):
validated_files.append(value)
validated_data.pop(key)
submission_instance = super().create(validated_data)
for file in validated_files:
BinaryFile.objects.create(submission=submission_instance, file=file)
return submission_instance
5. That's it!!!
Complete Code Snippet
# serializers.py
from rest_framework import serializers
from django.core.files.uploadedfile import InMemoryUploadedFile
class SubmissionSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
file_fields = kwargs.pop('file_fields', None)
super().__init__(*args, **kwargs)
if file_fields:
field_update_dict = field: serializers.FileField(required=False, write_only=True) for field in file_fields
self.fields.update(**field_update_dict)
def create(self, validated_data):
validated_data_copy = validated_data.copy()
validated_files = []
for key, value in validated_data_copy.items():
if isinstance(value, InMemoryUploadedFile):
validated_files.append(value)
validated_data.pop(key)
submission_instance = super().create(validated_data)
for file in validated_files:
BinaryFile.objects.create(submission=submission_instance, file=file)
return submission_instance
class Meta:
model = Submission
fields = '__all__'
# views.py
from rest_framework import status
from rest_framework import viewsets
class SubmissionAPI(viewsets.ModelViewSet):
queryset = Submission.objects.all()
serializer_class = SubmissionSerializer
def create(self, request, *args, **kwargs):
# main thing starts
file_fields = list(request.FILES.keys()) # list to be passed to the serializer
serializer = self.get_serializer(data=request.data, file_fields=file_fields)
# main thing ends
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)Screenhots and other stuffs
1. POSTMAN console
2. Django Shell
In [2]: Submission.objects.all()
Out[2]: <QuerySet [<Submission: Submission object>]>
In [3]: sub_obj = Submission.objects.all()[0]
In [4]: sub_obj
Out[4]: <Submission: Submission object>
In [5]: sub_obj.__dict__
Out[5]:
'_state': <django.db.models.base.ModelState at 0x7f529a7ea240>,
'id': 5,
'issued_at': datetime.datetime(2019, 3, 27, 8, 45, 42, 193943, tzinfo=<UTC>),
'completed': False,
'atomic_id': 1
In [6]: sub_obj.binary_files.all()
Out[6]: <QuerySet [<BinaryFile: uploads/binary/logo-800.png>, <BinaryFile: uploads/binary/Doc.pdf>, <BinaryFile: uploads/binary/invoice_2018_11_29_04_57_53.pdf>, <BinaryFile: uploads/binary/Screenshot_from_2019-02-13_16-22-53.png>]>
In [7]: for _ in sub_obj.binary_files.all():
...: print(_)
...:
uploads/binary/logo-800.png
uploads/binary/Doc.pdf
uploads/binary/invoice_2018_11_29_04_57_53.pdf
uploads/binary/Screenshot_from_2019-02-13_16-22-53.png
3. Django Admin Screenhot
edited Mar 27 at 9:05
answered Mar 26 at 10:29
JPGJPG
18.7k31141
18.7k31141
Not a duplicate as far as I can see. I get what you say, which is why I have created a create() function in SubmissionCreateSerializer() and created the BinaryFile object there. I guess my question becomes, with the models above, how do I apply validation to the child serializer?
– geekscrap
Mar 26 at 22:45
@geekscrap Check the updated answer :)
– JPG
Mar 27 at 9:08
@geekscrap did you try this?
– JPG
Mar 29 at 1:43
add a comment |
Not a duplicate as far as I can see. I get what you say, which is why I have created a create() function in SubmissionCreateSerializer() and created the BinaryFile object there. I guess my question becomes, with the models above, how do I apply validation to the child serializer?
– geekscrap
Mar 26 at 22:45
@geekscrap Check the updated answer :)
– JPG
Mar 27 at 9:08
@geekscrap did you try this?
– JPG
Mar 29 at 1:43
Not a duplicate as far as I can see. I get what you say, which is why I have created a create() function in SubmissionCreateSerializer() and created the BinaryFile object there. I guess my question becomes, with the models above, how do I apply validation to the child serializer?
– geekscrap
Mar 26 at 22:45
Not a duplicate as far as I can see. I get what you say, which is why I have created a create() function in SubmissionCreateSerializer() and created the BinaryFile object there. I guess my question becomes, with the models above, how do I apply validation to the child serializer?
– geekscrap
Mar 26 at 22:45
@geekscrap Check the updated answer :)
– JPG
Mar 27 at 9:08
@geekscrap Check the updated answer :)
– JPG
Mar 27 at 9:08
@geekscrap did you try this?
– JPG
Mar 29 at 1:43
@geekscrap did you try this?
– JPG
Mar 29 at 1:43
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55315158%2fmultiple-file-upload-drf%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
This is an interesting problem! I am thinking about how it is being serialized because each instance of the serializer has room for 1 'binary_file' and youre sending multiple fields labeled as 'binary_file.' I am wondering how the serializer is handling this, my fear is that it either saves the first or the last and the rest get thrown out. You could possibly fix this by having your view have 2 serializers, one to handle the files, the other for the remaining information. The serializer for the files could then loop for each occurrence of 'binary_file' and return an array of files?
– Scott Glascott
Mar 23 at 22:20
In terms of what it keeps, nothing 😀. I never get binary_files in the validated_data, if I send 1, 2, or more fields!
– geekscrap
Mar 24 at 11:51
I'm very new to DRF (and pretty new to Django), but I didn't know I could use multiple serializers! Can you link me?
– geekscrap
Mar 24 at 11:52