Изменение часового пояса на существующем проекте Django

Возможный дубликат --- Django REST: загрузка и сериализация нескольких изображений . ​​



Из документа Записываемый встраиваемый сериализатор DRF ,

По умолчанию вложенные сериализаторы доступны только для чтения. Если вы хотите поддерживать операции записи во вложенном поле сериализатора, вам нужно создать методы create() и / или update() , чтобы явно указывало, как отношения ребенка должны быть сохранены.

blockquote>

Из этого ясно, что дочерний сериализатор (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
img-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] POSTMAN console
2. Джанго Шелл

In [2]: Submission.objects.all()                                                                                                                                                                                   
Out[2]: ]>

In [3]: sub_obj = Submission.objects.all()[0]                                                                                                                                                                      

In [4]: sub_obj                                                                                                                                                                                                    
Out[4]: 

In [5]: sub_obj.__dict__                                                                                                                                                                                           
Out[5]: 
{'_state': ,
 'id': 5,
 'issued_at': datetime.datetime(2019, 3, 27, 8, 45, 42, 193943, tzinfo=),
 'completed': False,
 'atomic_id': 1}

In [6]: sub_obj.binary_files.all()                                                                                                                                                                                 
Out[6]: , , , ]>

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
[118 3]
3. Скриншот Django Admin enter image description here

5
задан Oli 27 March 2009 в 14:15
поделиться

1 ответ

Я сделал бы массовое обновление таблиц базы данных путем добавления или вычитания часов к/от полям даты и времени.

Что-то вроде этого работает в SQL Server и добавляет 2 часа к дате:

update tblName set date_field = dateadd("hh", 2, data_field)
3
ответ дан 15 December 2019 в 06:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: