GithubHelp home page GithubHelp logo

Comments (8)

remigermain avatar remigermain commented on June 3, 2024

Hi, are you sure you send this structure to parser ? tested on latest version, the result is what you expect:

from nested_multipart_parser import NestedParser
import pprint

# simulate your File class
class SimpleUploadedFile:
    def __init__(self, *args, **kwargs):
        self._val = (args, kwargs)
    
    def __repr__(self):
        return f"{type(self).__name__}(args={self._val[0]}, kw={self._val[1]})"

file_diploma = SimpleUploadedFile("file.png", b"file_content", content_type="image/png")
file1 = SimpleUploadedFile("file.pdf", b"file_content", content_type="application/pdf")
file2 = SimpleUploadedFile("file.txt", b"file_content", content_type="plain/text")

class TeachTypeEnum:
    FORMAL = 1

data = {
    'lang_id': 1,
    'file_diploma.file': file_diploma,
    'files[0].file': file1,
    'files[0].document_type_id': 13,
    'files[0].description': 'File description1',
    'files[1].file': file2,
    'files[1].document_type_id': 13,
    'files[1].description': 'File description2',
    'teach_type_code': TeachTypeEnum.FORMAL
}

p = NestedParser(data)
if p.is_valid():
    pprint.pprint(p.validate_data)
else:
    print(p.errors)

output:

{
    'file_diploma': {
        'file': SimpleUploadedFile(args=('file.png', b'file_content'), kw={'content_type': 'image/png'})
    },
    'files': [
        {
            'description': 'File description1',
            'document_type_id': 13,
            'file': SimpleUploadedFile(args=('file.pdf', b'file_content'), kw={'content_type': 'application/pdf'})
        },
        {
            'description': 'File description2',
            'document_type_id': 13,
            'file': SimpleUploadedFile(args=('file.txt', b'file_content'), kw={'content_type': 'plain/text'})
        }
    ],
    'lang_id': 1,
    'teach_type_code': 1
}

have you changed options in parser ?

from nested-multipart-parser.

lidyum avatar lidyum commented on June 3, 2024

It works when you give the data directly to the parser as you did. But it doesn't parse file types when I send it with request

I use this version
nested-multipart-parser==1.3.1
Django==3.2
djangorestframework==3.12.2

settings.py

REST_FRAMEWORK = {
    ...
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    'DEFAULT_PARSER_CLASSES': (
        'nested_multipart_parser.drf.DrfNestedParser',
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
        #'rest_framework.parsers.MultiPartParser'
    ),
    'NON_FIELD_ERRORS_KEY': 'detail',
    ...
}

serializers.py

class DocumentSerializerForParent(serializers.ModelSerializer):
    class Meta:
        model = DocumentModel
        fields = ['id', 'file']

class BulkDocumentSerializerForParent(serializers.ModelSerializer):
    document_type_id = serializers.PrimaryKeyRelatedField(queryset=DocumentTypeModel.objects.all(),
                                                          source='document_type', write_only=True)
    
    class Meta:
        model = DocumentModel
        fields = [ 'id', 'file', 'document_type_id', 'description'  ]


class PersonUniversitySerializer(serializers.ModelSerializer):
    file_diploma = DocumentSerializerForParent(required=False, allow_null=True)
    files = BulkDocumentSerializerForParent(many=True, required=False, allow_null=True)
    teach_type_code = serializers.IntegerField(source="teach_type", write_only=True)
    lang_id = serializers.PrimaryKeyRelatedField(queryset=LanguageModel.objects.all(), required=False,
                                                 allow_empty=True, allow_null=True, source='lang', write_only=True)

    def to_internal_value(self, data):

        ret_val = super().to_internal_value(data)  --> raise exception 

        # ******************************************
        # Exception 
        # {
        #     'file_diploma': {
        #          'file': ['No file was submitted.']
        #      }, 
        #      'files': [
        #             {
        #                  'file': ['No file was submitted.'], 
        #                 'document_type_id': ['This field is required.']
        #             }, 
        #             {
        #                 'file': ['No file was submitted.'], 
        #                 'document_type_id': ['This field is required.']
        #              }
        #       ]
        # }

        return ret_val

from nested-multipart-parser.

remigermain avatar remigermain commented on June 3, 2024

Ok, show me how you requests your api ( in js ? ) and try remove other parser for show error message.

The internal_value method raise a exception probably because NestPaser can't convert requests data .

If you call your api from js, you can use this lib is convert object js to flat object compatible with the nestedParser.

from nested-multipart-parser.

lidyum avatar lidyum commented on June 3, 2024

I'm experimenting with unit testing. Since the number of models is high, I only put one method here. Here is how I made the request.

    def test_create(self):

        file_diploma = SimpleUploadedFile("file.png", b"file_content", content_type="image/png")
        file1 = SimpleUploadedFile("file.pdf", b"file_content", content_type="application/pdf")
        file2 = SimpleUploadedFile("file.txt", b"file_content", content_type="plain/text")

        inst_person = self._create_natural_person()
        inst_lang = self._create_language()
        inst_section = self._create_university_section()
        inst_doc_type = self._create_document_type()

        post_data = {
            'person_id': inst_person.id,
            'section_id': inst_section.id,
            'start_year': 2000,
            'end_year': 2004,
            'lang_id': inst_lang.id,
            'file_diploma.file': file_diploma,
            'files[0].file': file1,
            'files[0].document_type_id': inst_doc_type.id,
            'files[0].description': 'File description1',
            'files[1].file': file2,
            'files[1].document_type_id': inst_doc_type.id,
            'files[1].description': 'File description2',
            'teach_type_code': TeachTypeEnum.FORMAL
        }

        url = reverse('betik_app_person:person-university-create')
        response = self.client.post(url, post_data, format="multipart")
        self.assertEqual(response.status_code, 201, response.data)

from nested-multipart-parser.

remigermain avatar remigermain commented on June 3, 2024

Change format to content_type

response = self.client.post(url, post_data, content_type="multipart")

from nested-multipart-parser.

lidyum avatar lidyum commented on June 3, 2024

AssertionError: 415 != 201 : {'detail': ErrorDetail(string='Unsupported media type "multipart" in request.', code='unsupported_media_type')}

In the class you made, I added a code to the place below. shouldn't he have it?

class DrfNestedParser(MultiPartParser):

    def parse(self, stream, media_type=None, parser_context=None):
        clsDataAndFile = super().parse(stream, media_type, parser_context)

        parser = NestedParser(clsDataAndFile.data.dict())
        
        #Shouldn't I put this here too?
        #parser_file = NestedParser(clsDataAndFile.files.dict())
        
        if parser.is_valid():
            return DataAndFiles(parser.validate_data, clsDataAndFile.files)
        raise ParseError(parser.errors)

from nested-multipart-parser.

remigermain avatar remigermain commented on June 3, 2024

And try without content_type
Files are added after check with wrapper DataAndFiles

Ok i have same error as you , il will fix that.

from nested-multipart-parser.

remigermain avatar remigermain commented on June 3, 2024

v.1.4.0 already on pipy,thanks to find this problemes ! i have add tests for nested files.

from nested-multipart-parser.

Related Issues (6)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.