GithubHelp home page GithubHelp logo

remigermain / nested-multipart-parser Goto Github PK

View Code? Open in Web Editor NEW
18.0 2.0 2.0 45 KB

Parser for nested data for 'multipart/form'

License: MIT License

Python 100.00%
parser python django-rest-framework multipart-formdata multipart json nested

nested-multipart-parser's Introduction

Hey im' remi !

corewar.mp4

Web Developer

Web developer and designer for 4 years, I'm listening to you at all times. In constant training I am up to date in all the latest technologies to offer them to my customers.

Im'm loving ❤️

  • Django / Drf
  • Postgres
  • Nuxt / Vuejs / React / Vite
  • Docker / Kubernetes
  • Jest / Vitests
  • Nginx
  • Unix
  • C / C++ / Rust
  • Vim / Vscode

nested-multipart-parser's People

Contributors

remigermain avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

nested-multipart-parser's Issues

Default separator to mixed or mixed-dot

Since technically a dictionnary can contain integer keys, it sounds more appropriate to default the separator to mixed or mixed-dot which will be less ambiguous on the type of structure to generate (array or dict).

The dot and bracket notation are more weakly typed:

data = {
		'title[0]': 'my-value',
		'title[1]': 'my-second-value'
	}

With bracket separator will generate:

{"title": ["my-value", "my-second-value]}

But we might want it to generate (even though it is rarer):

{"title": {0: "my-value", 1: "my-second-value"}}

Should parser response data be of type QueryDict or dict?

Maybe this is related to the structure of DRF, but I still wanted to write it here.

I am sending data like this;

post_data={
"detail":"Address detail",
"address.address":"Street 10",
"address.lat":"10",
"address.lng":"10"
}

Here is the desired result:

{
  "detail":"Address detail",
  "address":{
    "address":"Street 10",
    "lat":"10",
    "lng":10"
    }
  }

serializers.py

class ContentAddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = ContentAddressModel
        fields = ['address', 'lat', 'lng']


class ContentSerializer(serializers.ModelSerializer):
    address = ContentAddressSerializer(required=False, allow_null=True)
    
    class Meta:
        model = ContentModel
        fields = [ 'id', 'detail', 'address' ]

    def to_internal_value(self, data):
        #print("+" * 100, data)
        d = super().to_internal_value(data)
        #print("+" * 100, d) {"detail":"Address detail"} # no address!!

        return d

But, in the to_inernal_vale() method of ContentSerializer, it comes out as follows;

{"detail":"Address detail"} # no address!!

The data from your parser is as follows;
<QueryDict: {'detail': ['Address detail'], 'address': [{"address":"Street 10", "lat":"10","lng":10"}]}

As seen QueryDict comes. As I said, maybe it is related to the structure of DRF.

It works fully when I extend your parse() method and make the following change;

class NesteMultipartParser(DrfNestedParser):
    def parse(self, stream, media_type=None, parser_context=None):
        data = super().parse(stream, media_type, parser_context)
        dict_data = data.dict() #!!!!HERE!!!
        return dict_data

here i changed the return value to dict

Allow empty lists

Hey !

I found this library allowing multipart and nested writable data very helpful, thanks!

I encountered an issue when doing a PATCH request on a nested writable list serializer. I don't see how I can tell the difference between "not providing the attribute" (ie keep its existing value) and "ask to clear the list" (ie delete all elements in the list).

I think being able to provide an empty list would solve this issue, but looking at the code, I can't see any way to do it currently.

Here is an example of how it may work:

class SerializerWithNestedWritableList:
    some_list = SomeIntegerSerializer(many=True, required=False)

# No changes to current value
request.patch(url, data={})

# Replace all values by [1, 2, 3] 
request.patch(url, data={
    "some_list[0]": 1,
    "some_list[1]": 2,
    "some_list[2]": 3,
})

# Remove all values (empty list)
request.patch(url, data={
    "some_list[]": "",  # option 1
    "some_list": "",  # option 2
    "some_list": "[]",  # option 3
})

I think option 1 is the better, but I don't mind if any other option is selected.

Regards,

turning parsed QueryDict values to list

Describe the bug
while using it in DRF, it will return QueryDict with values type of list only , it will append all values to an extra list and return it with an extra layer of list.

To Reproduce
for example:
here is the multipart/FormDate sent by client in browser using react native:
ticket_detail[0][description]: some lorem ipsum
title: current subject
department: general-department
and here is the parsed QueryDict :
<QueryDict: {'ticket_detail': [[{'description': 'some lorem ipsum'}]], 'title': ['current subject'], 'department': ['general-department']}>

as you can see it parse the "title: current subject" to "'title': ['current subject']" with value type of a list, which was expected to be str.

Screenshots
image
image

and thank you for your great work!

Parser not working when sending dict array

I have a data like below

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")
post_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
        }

The output of the parser is as follows

<QueryDict: {
    'lang_id': ['1'], 
    'files': [
         [{
            'document_type_id': '13',
            'description': 'File description1'
          }, 
          {
              'document_type_id': '13', 
              'description': 'File description2'
           }]
    ], 
    'teach_type_code': ['1'], 
    'file_diploma.file': [<InMemoryUploadedFile: file.png (image/png)>], 
    'files[0].file': [<InMemoryUploadedFile: file.pdf (application/pdf)>], 
    'files[1].file': [<InMemoryUploadedFile: file.txt (plain/text)>]}
 >

As the output of the parser shows, 'files[0].file', 'files[1].file' and 'file_diploma.file' are not parsed.

Mixed separator configuration

It could be interesting to have a mixed mode for separator configurations, allowing us to use dots for objects and parentheses for array indexes, as in the following example:

	'simple_object.my_key: 'title'
	'simple_object.my_list[0]': True,
	'langs[0].id': 666,
	'langs[0].title': 'title',
	'langs[0].description': 'description',
	'langs[0].language': "language",
	'langs[1].id': 4566,
	'langs[1].title': 'title1',
	'langs[1].description': 'description1',
	'langs[1].language': "language1"

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.