django-rest-framework-bulk icon indicating copy to clipboard operation
django-rest-framework-bulk copied to clipboard

Allow for validation of the entire collection

Open sheluchin opened this issue 11 years ago • 2 comments

When creating, I have the need to validate the entire collection of items as a whole. For instance, there should be validation to ensure there are exactly three items present. At the moment, I do not see an easy way to accomplish this.

sheluchin avatar Apr 16 '14 19:04 sheluchin

Interesting though. Not sure how to handle that right now but will give it a though. If you want to implement that, PR would be welcome.

miki725 avatar Apr 16 '14 20:04 miki725

UPDATE: The below works, but I found out why overriding is_valid() didn't work - it needs to be overriden in the custom ListSerializer. If you just add a call to your custom validation method in there, you'll be fine :)


Not sure if it's still relevant for you @alex-netquity but here's how I handled the situation (admittedly not the most elegant fix).

  1. Create a list validation method in the Serializer
  2. Overwrite create() on the ModelViewSet so it's basically the same as inside BulkCreateModelMixin, with the exception of the added call to the list validation method:
def create(self, request, *args, **kwargs):
    self.serializer_class = CustomerBoxCreateSerializer

    # From here on copied from BulkCreateModelMixin in order to be able to call
    # the custom method is_valid_across_list() after is_valid()
    bulk = isinstance(request.data, list)

    if not bulk:
        return super(BulkCreateModelMixin, self).create(request, *args, **kwargs)

    else:
        serializer = self.get_serializer(data=request.data, many=True)
        serializer.is_valid(raise_exception=True)

        # Call to custom list validation method
        self.serializer_class().is_valid_across_list(data=serializer.validated_data, raise_exception=True)

        self.perform_bulk_create(serializer)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

Again, not the most elegant solution, but it works. I tried overwriting is_valid() directly on the serializer, but it never got executed since create() in BulkCreateModelMixin for some reason ends up calling the method on BaseSerializer.

Hope it helps! Let me know if you found a more elegant solution.

mtschammer avatar Nov 27 '15 15:11 mtschammer