Загруженный файл в Django Rest Framework и обработка запроса на zip - PullRequest
1 голос
/ 17 апреля 2020

Мне трудно понять, как обрабатывать HTTP-запрос из загруженного файла в Django Rest Framework. Конечная точка create в моем views.py :

def create(self, request):
    file_iobytes = request.FILES["file"].file
    self.zipping(file_iobytes)

    serializer = FileSerializer(data=request.data) # converts to JSON

    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)


def zipping(self, file):
    # Create a buffer to write the zipfile into
    zip_buffer = io.BytesIO()

    # Create the zipfile, giving the buffer as the target
    with zipfile.ZipFile(zip_buffer, 'w') as zip_file:
        #file.seek(0)
        zip_file.write(file)
        file.close()

models.py

class File(models.Model):
    file = models.FileField(upload_to='Myfiles/')
    ...

    def __str__(self):
        return self.file.name

serializers.py

class FileSerializer(serializers.ModelSerializer):
    class Meta:
        model = File
        fields = '__all__'
        read_only_fields = ('timestamp',)

Мое намерение таково:

  1. загрузить файл через DRF
  2. создать ха sh из файла, например, sha1 (чего я не делаю знаю, как напрямую, потому что для хеширования требуется путь, и я не знаю, как извлечь его из http-запроса).
  3. заархивировать файл и сохранить его

Как можно Я использую запрос для создания zip-файла (это правильный подход)?

1 Ответ

1 голос
/ 20 апреля 2020

Надеюсь, комментарии не требуют пояснений:)

import hashlib
from rest_framework.decorators import api_view
from rest_framework.response import Response


def generate_sha1(file_pointer):
    # BUF_SIZE is totally arbitrary, change for your app!
    BUF_SIZE = 65536  # lets read stuff in 64kb chunks!

    sha1 = hashlib.sha1()
    while True:
        data = file_pointer.read(BUF_SIZE)
        if not data:
            break
        sha1.update(data)
    return sha1.hexdigest()


def generate_zip(model_instance):
    source_file = f'{model_instance.file.name}'
    dest_file = f'{source_file}.zip'
    zipfile.ZipFile(dest_file, mode='w').write(source_file)
    return dest_file


def re_assign_files(model_instance, dest_file):
    model_instance.file.delete()  # deletes the uploaded file
    model_instance.file = dest_file  # mapping the generated zip file
    model_instance.save()  # saving the model instance


@api_view(http_method_names=['GET', 'POST'])
def foo_api(request):
    if request.method == 'GET':
        return Response({'message': 'this is get method'})
    else:
        serializer = FileSerializer(data=request.data)
        serializer.is_valid(True)  # validating the data
        <b>model_instance = serializer.save()  # saving the data into database

        hash_sha1 = generate_sha1(serializer.validated_data['file'])  # generates the SHA1 value
        dest_file = generate_zip(model_instance)  # generates zip file
        re_assign_files(model_instance, dest_file)
        return Response({'sha1': hash_sha1, 'data': serializer.data})</b>
...