0

I have a DRF backend and a Angular frontend. I'm trying to create a personal library app. I want to be able to send a file and a array of objects in the same post.

requirements.txt:

    asgiref==3.5.2
    cffi==1.15.1
    cryptography==38.0.3
    Django==4.1.2
    django-cors-headers==3.13.0
    django-filter==22.1
    django-rest-knox==4.2.0
    djangorestframework==3.14.0
    Markdown==3.4.1
    Pillow==9.3.0
    psycopg2==2.9.4
    pycparser==2.21
    pytz==2022.4
    sqlparse==0.4.3
    style==1.1.0
    update==0.0.1

This is the ViewSet:

    class BookViewSet(viewsets.ModelViewSet):
        parser_classes = [parsers.MultiPartParser, parsers.FileUploadParser]
        authentication_classes = []
        queryset = Book.objects.all()
        serializer_class = BookSerializer

        def create(self, request, *args, **kwargs):
            authors = json.loads(request.data['authors'])
            date = json.loads(request.data['publishedDate'])
            ISBN = json.loads(request.data['ISBN'])
            date = f"{date['year']}-{date['month']}-{date['day']}"
            request.data['publishedDate'] = date
            request.data['authors'] = authors
            request.data['ISBN'] = ISBN
            print(request.data)
            return super().create(request, *args, **kwargs)

This is the Serializer:

    class AuthorSerializer(serializers.ModelSerializer):
        class Meta:
            model = Author
            fields = ['name']


    class BookSerializer(serializers.ModelSerializer):
        authors = AuthorSerializer(many=True)

        def create(self, validated_data):
            print(validated_data)
            authors_data = validated_data.pop('authors')
            book = Book.objects.create(**validated_data)
            for author_data in authors_data:
                author = Author.objects.create(**author_data)
                author.books.add(book)
            return book

        def get_authors(self, obj):
            return AuthorSerializer(
                Author.objects.filter(books=obj),
                many=True
           ).data

        class Meta:
            model = Book
            fields = [
                'thumbnail',
                'title',
                'subtitle',
                'description',
                'ISBN',
                'pageCount',
                'publisher',
                'publishedDate',
                'authors',
            ]    

This is the print result in the ViewSet:

    <QueryDict: {'title': ['"title"'], 'subtitle': ['"subtitle"'], 'description': ['"description"'], 'ISBN': ['99999999'], 'pageCount': ['123'], 'publisher': ['"publisher"'], 'publishedDate': ['2022-5-5'], 'authors': [[{"name":"author1"}, {"name":"author2"}]], 'thumbnail': [<TemporaryUploadedFile: file.jpg (image/jpeg)>]}>

It errors out in the validation because it doesn't print the validated_data and returns a response that the authors field is required.

I've tried sending a string in the authors field like this:

    'authors': '[{"name":"Author"}]'

And it prints the validated_data, but without the authors field.

    {'thumbnail': <TemporaryUploadedFile: file.jpg (image/jpeg)>, 'title': '"Livro"', 'subtitle': '"E seu Subtítulo"', 'description': '"Description"', 'ISBN': 1546789, 'pageCount': 123, 'publisher': '"Editora"', 'publishedDate': datetime.date(2022, 5, 5)}

When sending as application/json and without the file the many-to-many field works.

I couldn't get clear answers with these links: https://stackoverflow.com/questions/64500753/django-rest-framework-serialize-an-array-in-a-multipart-form-data-request https://stackoverflow.com/questions/19780731/django-rest-framework-serializer-field-required-false

0 Answers0