4

This is what I have so far.

My serializer:

class MySerializer(serializers.ModelSerializer):

     class Meta:
         model = MyModel
         fields = ('field_1', 'field_2', 'field_3')

My ModelViewset

class MyViewSet(ModelViewSet):

    serializer_class = MySerializer
    model = MyModel
    queryset = MyModel.objects.all().order_by('date_paid')

    def create(self, request, *args, **kwargs):
        many = True if isinstance(request.data, list) else False
        serializer = MySerializer(data=request.data, many=many)
        if serializer.is_valid():
            serializer.save()
        else:
            return Response(serializer.errors, 
status=status.HTTP_400_BAD_REQUEST)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

My main concern is that when testing the endpoint to create multiple objects using the following payload, on the view the property request.data seem to be empty, as a result it returns errors of fields missing.

{
        'data': [
            {
                'type': 'MySerializer',
                'attributes': {
                    'field_1': 1,
                    'field_2': 0.05,
                    'field_3': 'abc'
                }
            },
            {
                'type': 'MySerializer',
                'attributes': {
                    'field_1': 1,
                    'field_2': 0.05,
                    'field_3': 'abc'
                }
            },
            {
                'type': 'MySerializer',
                'attributes': {
                    'field_1': 1,
                    'field_2': 0.05,
                    'field_3': 'abc'
                }
            }
        ]
    }

However when using a single object instance:

{
        'data': {
            'type': 'MySerializer',
            'attributes': {
                    'field_1': 1,
                    'field_2': 0.05,
                    'field_3': 'abc'
            }
        }
    }

It seeems to work just fine and the object is created.

I have tried several ways to accomodate the payload:

  • Placing the list of objects inside the attributes field.
  • Placing the list of instances directly on the data field but it returns either an object error, or and empty request.data

How am I supposed to send the data for multiple objects, is it even possible, I have read in many articles that just by placing many=True on the serializer instance is enough to accomplish this but I just cant't get the data from the request.

Any step that I missed or another workaround?

EDIT

Forgot to mention two things

  1. that I'm using django rest framework json api library, could that be the reason why the data is empty?
  2. I placed dictionaries since I'm testing the endpoints and I use json.dumps(payload) when sending data.
1
  • Why you don't set ` many = isinstance(request.data, list)`? Avoid redundant code. Commented Oct 3, 2021 at 23:15

1 Answer 1

4

Ok, I am actually surprised that the creation of a single object instance works, since the data doesn't seem to be in the correct format. When the many argument is used, the serializer expects a list but what you send is a json object.

This is what the JSON should like:

    [
        {

              "field_1": 1,
              "field_2": 0.05,
              "field_3': "abc"

        },
        {

              "field_1": 1,
              "field_2": 0.05,
              "field_3': "abc"

        },
        {

              "field_1": 1,
              "field_2": 0.05,
              "field_3': "abc"

        }
    ]

These are the points to note here:

  1. The JSON begins with a list
  2. The fields are directly in the body of each object - no type or attribute field, expect you implement the logic to parse that in your serializer
  3. JSON does not using single quotes but double quotes

Did you inpect the request.data to confirm that it is empty as you said? If so, then that is another issue altogether as it may be a parsing issue.

EDIT: Using JSON API

After a little digging in the Rest framework json api github page, I found this issue requesting support for bulk operations. Apparently, they added it in this pull request and you can see the correct format of multiple objects in the comments.

Yours should be like this:

{
"data": [
    {
        "type": "MySerializer",
        "attributes": {
            "field_1": 1,
            "field_2": 0.05,
            "field_3": "abc"
        }
    },
    {
        "type": "MySerializer",
        "attributes": {
            "field_1": 1,
            "field_2": 0.05,
            "field_3": "abc"
        }
    },
    {
        "type": "MySerializer",
        "attributes": {
            "field_1": 1,
            "field_2": 0.05,
            "field_3": "abc"
        }
    }
]

}

Most likely the parser couldn't parse the data in the format you provided and that's why your request.data is empty.

EDIT 2:

While the bulk operations feature has not been integrated in the json-api specs, the Django Rest JSON-API already added a special parser for it. So you'll have to add this parser JSONAPIBulkParser for it to work. Check out this comment in the PR

Sign up to request clarification or add additional context in comments.

6 Comments

I do debug the request to check the request.data property and also have tried what you suggested, however since I'm using the django rest framework json api library "type" and "attributes" are required, as far as I know.
Ok, that's a whole different story. So you're sure that request.data is always empty? it means the json api parser class is not able to pass it corrctly
It's only empty when I try to send multiple objects, when I send a single instance everything works as expected.
I've tried what you suggested, and the data remains empty, also checked both links above but according to the thread on drf json api it seems that they are still waiting for this pull request to be approved for they to apply the changes on the library.
@erick.chali the PR is still open in the JSON API specification but django rest json api already implemented a parser for it. Check out github.com/django-json-api/django-rest-framework-json-api/pull/…. You'll have to use this particular parser for it to work
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.