только ради свойств объекта мыслящего объекта из временной шкалы:
var foo = {
a: function(){return 5}(),
b: function(){return 6}(),
c: function(){return this.a + this.b}
}
console.log(foo.c())
также есть более высокие ответы . Вот как я модифицировал пример кода, с которым вы допросили.
UPDATE:
var foo = {
get a(){return 5},
get b(){return 6},
get c(){return this.a + this.b}
}
// console.log(foo.c);
Возможный дубликат --- Django REST: загрузка и сериализация нескольких изображений .
Из документа Записываемый встраиваемый сериализатор DRF ,
По умолчанию вложенные сериализаторы доступны только для чтения. Если вы хотите поддерживать операции записи во вложенном поле сериализатора, вам нужно создать методы
blockquote>create()
и / илиupdate()
, чтобы явно указывало, как отношения ребенка должны быть сохранены.Из этого ясно, что дочерний сериализатор (
BinaryFileSerializer
) не будет вызывать свой собственный методcreate()
, если не вызывается явно.
Цель вашего запроса
HTTP POST
- создать новый экземплярSubmission
(и экземплярBinaryFile
) , Процесс создания проходит по методуcreate()
сериализатораSubmissionCreateSerializer
, который вы должны переопределить. Таким образом, он будет действовать / выполняться в соответствии с вашим кодом.
ОБНОВЛЕНИЕ-1
Что нужно запомнить
1. AFAIK, мы не можем отправить вложенныхmultipart/form-data
[ 1165]
2. Здесь я только пытаюсь реализовать сценарий наименьшего случая
3. Я тестирую это решение с POSTMAN Инструмент тестирования остальных API.
4. Этот метод может быть сложным (пока мы не нашли лучший).
5. Предполагая, что ваш класс представления является подклассом классаModelViewSet
[1146] Что я собираюсь делать? [1198 ]
1. Поскольку мы не можем отправлять файлы / данные во вложенном виде, мы должны отправлять их в плоском режиме.
image-1
2. Переопределите метод__init__()
сериализатораSubmissionSerializer
и динамически добавьте столько же атрибутаFileField()
в соответствии сrequest.FILES
[11103 ] data.
Мы могли бы как-то использовать здесьListSerializer
илиListField
. К сожалению, я не смог найти способ: (# 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)
Итак, что здесь ID
file_fields
?
Поскольку форма -data - это пара ключ-значение , все данные файла должны быть связаны с ключом. Здесь, в image-1 , вы можете увидетьfile_1
иfile_2
.
3. Теперь нам нужно передать значенияfile_fields
изview
. Так как эта операция создает новый экземпляр, нам нужно переопределитьcreate()
Метод API-класса .# 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. Теперь все значения будут правильно сериализованы. Настало время переопределить [ 11112]create()
методSubmissionSerializer()
для сопоставления отношений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. Вот и все! !!
Полный фрагмент кода
# 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)
Снимки экрана и другие материалы
1. Консоль POSTMAN
[ 1160]
2. Джанго Шелл
[118 3]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