We have a model with only one fields (Name). We want to send a list of dictionaries and create multiple objects for this model in one POST request. The model, serializer, view and mixin is mentioned below:
models.py
class Manufacturer(models.Model):
"""
The Measure Unit Category Table contains the categories
of measurement units (example: weight, length, temperature,etc)
"""
name = models.CharField(verbose_name=_("Manufacturer Name"),
help_text=_("Required. Example: Ford, Tesla, Hyundai"),
max_length=63,
unique=True)
class Meta:
verbose_name = _("Manufacturer")
verbose_name_plural = _("Manufacturers")
ordering = ('name',)
def __str__(self):
return self.name
serializers.py
class ManufacturerSerializer(serializers.ModelSerializer):
class Meta:
model = Manufacturer
fields = '__all__'
mixins.py
class CreateModelMixin(object):
def get_serializer(self, *args, **kwargs):
# add many=True if the data is of type list
if isinstance(kwargs.get("data", {}), list):
kwargs["many"] = True
return super().get_serializer(*args, **kwargs)
views.py
class ManufacturerCreateView(CreateModelMixin, generics.CreateAPIView):
"""
Create View for Manufacturer
"""
queryset = Manufacturer.objects.all()
serializer_class = ManufacturerSerializer
permission_classes = (IsAuthenticated,)
With the above code, I'm able to create multiple objects with one POST request.
I've written the below test case using pytest:
def test_create_manufacturer_list_of_objects(self, authenticated_client):
data = [
{
"name": "Test11"
},
{
"name": "Test12"
}
]
response = authenticated_client.post(reverse('manufacturer-create'), data)
assert response.status_code == 201
urls.py
path('create-manufacturer/',
ManufacturerCreateView.as_view(),
name='manufacturer-create'),
When I run the above, I get the error - AttributeError: 'list' object has no attribute 'items'. This is a little confusing as the API works without any errors but the test case fails. Can you please guide on correcting this issue?
I tried overriding the POST method, and including the above code in serializers instead of mixins, but it gives the same error.
Passing the "format=json" when calling the post method resolved the issue. Modified the test url to below:
response = authenticated_client.post(reverse('manufacturer-create'), data, format=json)